Multithreading Java线程-同步don

Multithreading Java线程-同步don,multithreading,locking,synchronized,Multithreading,Locking,Synchronized,所以我对代码的问题是,为什么“synchronized”不阻止这些线程之间的竞争? 当线程1从shared获取/设置值时,应该锁定线程2,但结果仍然是“线程2看到1” 像这样更改代码。我添加了一个额外的日志语句,只是为了证明它正在运行。现在让我解释一下这个问题。您刚刚将修改共享状态的方法声明为 public class SetGetFail implements Runnable { // Every thread is assigned a number and has a reference

所以我对代码的问题是,为什么“synchronized”不阻止这些线程之间的竞争?
当线程1从shared获取/设置值时,应该锁定线程2,但结果仍然是“线程2看到1”

像这样更改代码。我添加了一个额外的日志语句,只是为了证明它正在运行。现在让我解释一下这个问题。您刚刚将修改共享状态的方法声明为

public class SetGetFail implements Runnable {
// Every thread is assigned a number and has a reference to a SharedObject.
// In main(), a single SharedObject is passed to all threads.
int number;
SharedObject shared;

public SetGetFail(int no, SharedObject so) {
number = no;
shared = so;
}

public static void main(String[] args) {
SharedObject shared = new SharedObject(0);
    new Thread(new SetGetFail(1, shared)).start();
    new Thread(new SetGetFail(2, shared)).start();
}

synchronized public void run() {
    setGet();
}

synchronized void setGet() {
// Repeatedly assign this thread's own number to the shared
// object and race to read that number again.
// Exit, if some other thread modified the number in between.
while(true) {
    shared.setNo(number);
    int no = shared.getNo();
    if (no != number) {
    System.out.println("Thread " + number + " sees " + no);
    System.exit(no);
    }
}
}}
因此,每个线程都会获得自己的锁,并同时修改共享数据。这就是为什么线程2看到由另一个线程设置的值1。为了保护这一点,您需要使用thread1和thread2实例所共有的锁。为此,您需要使用一个显式锁对象,该对象在两个线程之间共享,并使用该共享锁进行同步。这就是我为解决这个问题所做的

synchronized void setGet() {
    // ...
}

谢谢你的努力,但我的目的是理解为什么代码中会有种族?在本例中,哪个线程被锁定(由谁锁定),因此结果类似于线程2看到的1。但通过此声明,锁定的对象是否为“共享对象”?
静态对象在所有实例中共享。因此,当一个线程在受保护的块中时,另一个线程必须等待。这就避免了比赛状态的发生。让我困惑的不是你的解决方案。为什么在这种情况下(给定的代码)会有一场竞赛。因为锁定的对象是共享实例?Synchronize是否阻止了一个线程或那里发生了什么?这不是我的密码。。
private static final Object lock = new Object();

synchronized (lock) {
    // ...
}


public class SetGetFail implements Runnable {
    // Every thread is assigned a number and has a reference to a SharedObject.
    // In main(), a single SharedObject is passed to all threads.
    int number;
    SharedObject shared;

    private static Object lock = new Object();

    public SetGetFail(int no, SharedObject so) {
        number = no;
        shared = so;
    }

    public static void main(String[] args) throws InterruptedException {
        SharedObject shared = new SharedObject(0);
        new Thread(new SetGetFail(1, shared), "One").start();

        new Thread(new SetGetFail(2, shared), "Two").start();

    }

    synchronized public void run() {
        setGet();
    }

     void setGet() {
        // Repeatedly assign this thread's own number to the shared
        // object and race to read that number again.
        // Exit, if some other thread modified the number in between.
        while (true) {
            synchronized (lock) {
                shared.setNo(number);
                int no = shared.getNo();
                if (no != number) {
                    System.out.println("Thread " + number + " sees " + no);
                    System.exit(no);
                }
                System.out.println("Thread " + number + " sees " + no);
            }

        }
    }

}