Java 整数对象的同步块
我刚刚在Java中遇到了synchronized块,并编写了一个小程序来测试它是如何工作的 我创建了10个线程,让每个线程增加一个整数对象1000倍 因此,对于同步,我假设在所有线程完成它们的工作之后,结果是10000,而在没有同步的情况下,结果是少于10000 然而,同步并不像我预期的那样是wokring 我猜这与对象的不变性有关 我的节目:Java 整数对象的同步块,java,synchronization,Java,Synchronization,我刚刚在Java中遇到了synchronized块,并编写了一个小程序来测试它是如何工作的 我创建了10个线程,让每个线程增加一个整数对象1000倍 因此,对于同步,我假设在所有线程完成它们的工作之后,结果是10000,而在没有同步的情况下,结果是少于10000 然而,同步并不像我预期的那样是wokring 我猜这与对象的不变性有关 我的节目: public class SyncTest extends Thread{ private static Integer syncObj =
public class SyncTest extends Thread{
private static Integer syncObj = new Integer(0);
private static SyncTest[] threads = new SyncTest[10];
private boolean done = false;
public void run(){
for(int i = 0; i < 1000; i++){
synchronized(syncObj){
syncObj ++;
}
}
done = true;
}
public static void main(String[] args) {
for(int i=0; i < threads.length; i++){
threads[i] = new SyncTest();
threads[i].start();
}
while(!allDone()); //wait until all threads finished
System.out.println(syncObj);
}
private static boolean allDone(){
boolean done = true;
for(int i = 0; i < threads.length; i++){
done &= threads[i].done;
}
return done;
}
}
有人能澄清一下吗?这些操作通常是用原子来完成的。看一看这些结构是专门为多线程计算而设计的。正常的实现不是线程安全的。syncObject在每次您对它进行++操作时都会发生更改++会将它转换为一个基本的int,增加它,然后将它自动装箱回Integer对象。整数对象是不可变的。。。一旦它们被创建,它们就无法更改 最重要的是,您并不是在所有线程中都使用相同的syncPObj,不同的线程在不同的时间使用不同的SyncObject进行同步 使用一个对象作为同步调用它syncObj,并将其声明为最终对象:
private static final Object syncObject = new Object();
那么您的计数器应该是perofrmance的基本int,称之为“counter”或其他什么
在syncObject和增量计数器上同步
编辑:根据@jsn,done标志也被打破了,因为您的代码在isAllDone方法上有一个“紧循环”,这是一个糟糕的做法。您应该使用线程[i]。join在每个线程完成时等待阻塞,然后从中检查状态。使用ExecutorService是“正确的方法”。假设这是因为Integer对象的不变性 我已将同步块更改为
Integer old = syncObj;
syncObj ++;
System.out.println(syncObj == old);
我的控制台充满了谎言
因此,每次我增加整数,就会创建一个新对象
因此,我只读取旧对象,它不会被锁定。但是同步并不像预期的那样工作。-发生了什么意外情况?@jsn volatile不是必需的,因为其他线程没有更改它。@Ravi,你说得对。它不会在线程外更改。我仍然担心主线程可能会将它们中的每一个缓存为false。@jsn您是对的,主线程可能不会获取设置为true的值。OP应该使用线程[i]。joinIt不仅仅是缓存部分,它是waitingOP试验同步时100%CPU的紧密循环。