Java 使对象同步后同步不起作用
我已经同步了Integer对象a,我期望输出1 2 3 4 5 6 7 8 9 但它仍然给了我其他的输出,问题出在哪里,因为我已经同步了每个线程试图访问的变量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++;
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
使此类错误发生的可能性大大降低。