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;
}
}
public类SyncTest扩展线程{
私有静态整数syncObj=新整数(0);
私有静态SyncTest[]线程=新SyncTest[10];
私有布尔完成=假;
公开募捐{
对于(int i=0;i<1000;i++){
已同步(syncObj){
syncObj++;
}
}
完成=正确;
}
公共静态void main(字符串[]args){
对于(int i=0;i
有人能澄清一下吗?这些操作通常是用
原子的来完成的。看一看。这些结构是专门为多线程计算而设计的。正常的实现不是线程安全的。syncObject在您每次对其进行++操作时都会进行更改(++将其转换为基本整数,递增,然后将其自动装箱回Integer对象。Integer对象是不可变的…一旦创建,它们就无法更改
最重要的是,您并不是在所有线程中都使用相同的syncPObj,不同的线程在不同的时间使用不同的SyncObject进行同步
使用一个对象作为同步(称为syncObj),并将其声明为最终对象:
private static final Object syncObject = new Object();
那么你的计数器应该是perofrmance的原语(int),称它为“counter”或其他什么
在syncObject和增量计数器上同步
编辑:根据@jsn,done标志也被破坏,因为您的代码在isAllDone()方法上有一个“紧循环”,这是一种不好的做法。您应该使用thread[i].join()等待(阻塞)在每个线程完成时,然后从中检查状态。使用ExecutorService是“正确的方法”。假设这是因为Integer对象的不可变性
我已将同步块更改为
Integer old = syncObj;
syncObj ++;
System.out.println(syncObj == old);
我的控制台中充满了false
s
因此,每当我增加整数时,就会创建一个新对象
因此,我只读取旧对象,它不会被锁定。但是同步并不像预期的那样工作。-发生了什么意外情况?@jsnvolatile
不是必需的,因为其他线程没有更改done
。@Ravi,你是对的。它在线程之外没有更改。我仍然很担心假设主线程可能会将每个线程缓存为false。@jsn您是对的,主线程可能不会获取设置为true的值。OP应该使用线程[i]。join()这不仅仅是缓存部分,而是waitingOP在试验synchronized(
)时的紧密循环(100%CPU)。