一段java并发同步示例代码的疑惑

importjava.util.ArrayList;
importjava.util.concurrent.Callable;
importjava.util.concurrent.ExecutionException;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
importjava.util.concurrent.Future;
publicclassCachedThreadPool{
privatestaticintid=0;
publicstaticvoidmain(String[]args){
newCachedThreadPool().fun();
}
privatevoidfun(){
ExecutorServiceexe=Executors.newCachedThreadPool();
ArrayList>list=newArrayList>();
for(inti=0;i<3;i++){
list.add(exe.submit(newTaskCall()));
}
for(Futurefs:list){
try{
System.out.println(fs.get());
}catch(InterruptedExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(ExecutionExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
exe.shutdown();
}
privatesynchronizedStringgetId(){
return++id+"";
}
classTaskCallimplementsCallable{
@Override
publicStringcall()throwsException{
//TODOAuto-generatedmethodstub
returngetId();
}
}
}
这段代码并没有什么问题,但是为何把getId()函数放到TaskCall内部,却会得到同步失败的输出(223或者333等),这是为什么呢?
ibeautiful
浏览 279回答 2
2回答

白板的微信

因为放到TaskCall里之后,synchronized表示在一个TaskCall实例上同步执行。有3个实例,它们之间是不同步的。而放在外面是在一个CachedThreadPool中同步。

一只斗牛犬

按你的测试代码,楼上回答能解释。然而:测试代码有错误,以下是正确的测试代码:importjava.util.ArrayList;importjava.util.Collections;importjava.util.List;importjava.util.concurrent.*;publicclassCachedThreadPool{privatestaticintid=0;privatestaticListresults=Collections.synchronizedList(newArrayList());publicstaticvoidmain(String[]args)throwsException{newCachedThreadPool().fun();}privatevoidfun()throwsException{ExecutorServiceexe=Executors.newCachedThreadPool();Listlist=newArrayList();for(inti=0;i
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript