Java 使对象同步后同步不起作用

Java 使对象同步后同步不起作用,java,multithreading,Java,Multithreading,我已经同步了Integer对象a,我期望输出1 2 3 4 5 6 7 8 9 但它仍然给了我其他的输出,问题出在哪里,因为我已经同步了每个线程试图访问的变量 package thread; public class BasicThread extends Thread { static Integer a=new Integer(0); void incr() { synchronized (a) { a++;

我已经同步了Integer对象a,我期望输出1 2 3 4 5 6 7 8 9 但它仍然给了我其他的输出,问题出在哪里,因为我已经同步了每个线程试图访问的变量

package thread;
public class BasicThread extends Thread {
    static Integer a=new Integer(0);
    void incr() {
        synchronized (a) {          
            a++;
            System.out.println(a);
        }
    }

    public void run() {
        incr();
        incr();
        incr();
    }

    public static void main(String[] args) throws InterruptedException {

        BasicThread bt=new BasicThread();
        BasicThread bt1=new BasicThread();
        BasicThread bt2=new BasicThread();

        bt.start();
        bt1.start();
        bt2.start();
    }
}

请注意:整数对象是不可变的。所以,这里发生的是:每次你做一个“a++”。。。编译器实际上执行自动装箱;最后。。。将创建一个新的整数对象

为了使代码正常工作,所有方法调用的锁(正在同步的对象)必须相同

换句话说:对一个不断变化的对象的引用。。。不适合用作锁。相反,请执行以下操作:

private final static Object LOCK = new Object();
(如果使用final有助于确保此对象引用不会随时间而改变),然后:

synchronized(LOCK)

使用唯一的对象进行同步。当您更改整数时,会创建一个新的整数,因为它们是不可变的

例如:

public class BasicThread extends Thread {
    static Integer a = new Integer(0);
    private static String ab = "";

    void incr() {
        synchronized (ab) {
            a++;
            System.out.println(a);

        }
    }

    public void run() {

        incr();
        incr();
        incr();
    }
}

你得到了什么输出?@james将我的函数设置为静态也解决了我的问题。这是正确的方法吗?将我的函数设置为静态会出现什么类型的问题。静态整数a=新整数(0);同步静态void incr(){{a++;System.out.println(a);}}将
static
添加到
incr()
函数的声明中不会改变程序的功能。它不依赖于任何实例变量,因此无论是实例方法还是
静态
方法都没有区别。程序的问题在于语句
a++
分配了变量
a
。也就是说,在
a++
之前,变量表示一个对象,在
a++
之后,变量表示另一个对象。这意味着您的线程可能正在不同的对象上同步,这不会阻止它们在
synchronized
块中并发运行。您可以强调,您的
LOCK
声明中的
final
使此类错误发生的可能性大大降低。