1. 什麼是棧封閉?安全
答:棧封閉是線程封閉的一種特例,在棧封閉中,只能經過局部變量才能訪問對象。它們位於執行線程的棧中,其餘線程沒法訪問這個棧。「棧封閉」是實現「線程封閉」的機制之一,而「線程封閉」和線程安全性相關。spa
2. 什麼狀況下對象引用的棧封閉性會被破壞」,破壞掉的後果是什麼?線程
答:code
1 private ArrayList<Animal> animals; //成員變量 2 public void test() { 3 Animal cat = new Animal("小花貓"); //局部變量 4 animals.add(cat); 5 cat.setAge(1); 6 }
上面這段代碼執行到 "animals.add(cat); " 時,cat對象逸出了(「逸出」這一律念在註釋中作了解釋),即cat對象引用的棧封閉性被破壞了。對象
爲何說cat對象逸出了呢?看代碼咱們能夠知道animals是成員變量,是支持多個線程同時訪問的共享數據。當代碼執行到「animals.add(cat); 」時,除了當前線程外,其餘線程也能同時經過animals來訪問到cat,你並不能保證其餘線程同時會對cat作什麼訪問操做,因此cat在這裏被不正確地發佈了,即cat逸出了。blog
因此:局部變量錯誤被髮布出去了就會致使封閉性被破壞,並致使對象的逸出。作用域
3. 注:class
「逸出」是和線程安全相關的知識點,「逸出」是「發佈」時的一種狀況。test
「發佈(Publish)」一個對象的意思是指,使對象可以在當前做用域以外的代碼中使用。如:將一個指向該對象的引用保存到其餘代碼能夠訪問的地方,或者在某一個非私有的方法中返回該引用,或者將引用傳遞到其餘類的方法中。變量
「逸出(Escape)」:當某個不該該發佈的對象被髮布了。(其實逸出就是將還沒有完成構造的對象發佈出去了,因此,避免對象逸出就須要確保對象已經完成初始化了再發布。)