按你的測(cè)試代碼,樓上回答能解釋。然而:測(cè)試代碼有錯(cuò)誤,以下是正確的測(cè)試代碼: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();List>list=newArrayList<>();for(inti=0;i<100;i++){list.add(exe.submit(newTaskCall()));}exe.shutdown();for(Futurefs:list){fs.get();}//斷言for(inti=1;iif(results.get(i)!=results.get(i-1)+1){thrownewIllegalStateException();}}System.out.println("\n"+results);}privatesynchronizedStringgetId(){++id;System.out.print(id+",");results.add(id);returnid+"";}classTaskCallimplementsCallable{@OverridepublicStringcall()throwsException{returngetId();}}}然后是分析:先翻譯幾處代碼,以便理解:1.privatesynchronizedStringgetId(){return++id+"";}等價(jià)于privateStringgetId(){synchronized(this){return++id+"";}}2.//TaskCallreturngetId();等價(jià)于//TaskCallreturnCachedThreadPool.this.getId();可以看到同步范圍僅限于this,也就是CachedThreadPool的實(shí)例,只有一個(gè)。但是static字段是類的字段,不是實(shí)例的字段,因此不在加鎖范圍!然而,同步會(huì)刷新代碼塊內(nèi)所有用到的變量,不論static與否。而唯一實(shí)例使++代碼塊被單線程獨(dú)占。兩者結(jié)合,意外地做到了并發(fā)安全。還可以試驗(yàn)一下,synchronized改成synchronized(CachedThreadPool.class){...},并把main標(biāo)為synchronized,會(huì)導(dǎo)致死鎖。synchronized的知識(shí):指定了一個(gè)同步范圍,進(jìn)出范圍時(shí)會(huì)刷新相關(guān)變量,阻止其他線程進(jìn)入該范圍。synchronizedmethod的范圍是this,synchronizedstaticmethod的范圍是class。補(bǔ)充:如果同一個(gè)類有的方法寫了synchronized,有的方法沒寫,也達(dá)不到同步。