public class Test { static ExecutorService pool = Executors.newFixedThreadPool(2000); public static void main(String[] arg){ List<Callable<String>> tasks = new LinkedList<>(); for(int i=0;i<2000;i++){ tasks.add(()->{ System.out.println(Thread.currentThread().getName()+":"+Instance.getInstance()); return ""; }); } try{ pool.invokeAll(tasks); }catch (InterruptedException e){ e.printStackTrace(); } System.out.println("完成---》"); } }
class Instance{ volatile static Instance instance = null; public static Instance getInstance(){ if(instance==null){ System.out.println(Thread.currentThread().getName()+": ready in"); synchronized(instance){ System.out.println(Thread.currentThread().getName()+": in"); if(instance==null){ System.out.println(Thread.currentThread().getName()+":實例化"); instance = new Instance(); } } } return instance; } private static class InnerInstance{ static Instance instance = new Instance(); } public static Instance getInstance2(){ return InnerInstance.instance; } }
以上是單例模式的 使用雙重鎖 和 內部類的實現方式,線程
當時你會發如今對instance加鎖的時候,不會有一個線程闊以拿到這個鎖,由於空對象應該虛擬機不會分配一個monitor,也就拿不到鎖了對象
因此你必須得修改爲對一個obj的加鎖get
static Object obj = new Object();虛擬機
synchronized(obj){......}it
這樣;io
還有爲什麼要在instance 前面加一個volatile?class
因爲volatile可見性,否則會出現實例化屢次的結果。List