摘要:引用逸出基于外部方法發布對象引出引用逸出問題。并發編程實戰的提到私有構造函數公共的工廠方法解決可能逸出的問題。同理在構造函數可以新建線程,當不要。下面代碼就是錯誤的可以在構造函數中但是不要
java并發編程實戰的解釋,不夠詳細,尤其this引用逸出讓人理解有些費解,java并發編程實戰里面的內容就直接拷貝過來
發布:使對象能夠在當前作用域之外的代碼中使用 逸出:當某個不該被發布的對象被發布時,這種情況稱為逸出 發布內部狀態將會破壞封裝性,并使得程序難以維持不變性條件 當某個對象逸出后,必須對程序進行分析,以便找出哪些對象或線程可能會誤用該對象,這正是使用封裝的最主要原因:使對程序的正確性分析變為可能,并使無意中破壞設計約束條件變得更難 無論其它的線程會對逸出的對象引用執行何種操作,都不重要,因為誤用該引用的風險始終是客觀存在的發布的實現方式 1.對象引用作為非私有屬性
代碼示例:
//只是代碼示例,不推薦這樣初始化List public class test { public Listanimals = new ArrayList (){{ add(new Animal()); }}; }
List對象和List中的Animal對象都被發布出去。
2.對象引用被非私有方法返回代碼示例:
//只是代碼示例,不推薦這樣初始化List public class test { private Listanimals = new ArrayList (){{ add(new Animal()); }}; public List getAnimals(){ return animals; } }
1、2的一樣,List對象和List中的Animal對象發布出去。只是一個是方法發布出去,一個是屬性發布出去。
3.外部方法發布對象外部方法定義: 對當前類來說,外部方法是指行為不完全由當前類來規定的方法,包括其他類中定義的方法以及當前類中可以被改寫的方法(既不是私有方法,也不是final方法)
代碼示例:
public class test { public void setAnimals(Animal animal){ animal.setDag( new Dog(){ public void doSomething(){ ... }; } ) } }
當前類test來說,setDag為外部方法,Dog就被發布了。
this引用逸出基于外部方法發布對象引出this引用逸出問題。直接拿java并發編程實戰的代碼
public class ThisEscape { public ThisEscape(EventSource source){ source.registerListener( new EventListener(){ public void onEvent(Event e){ doSomething(e) } }); } } java并發編程實戰的解釋: 當ThisEscape發布EventListener時,它也無條件地發布了封裝(enclosing)ThisEscape的實例,因為內引類(inner class inst ances)的實例包含了對封裝實例隱含的引用。
這里發布new EventListener()內部對象,隱式的有個this。也就是ThisEscape也會被發布出去,但是ThisEscape還沒有構建完成,存在逸出的可能,ThisEscape在未構建完成被發布了。怎么處理這個可能逸出的問題,就是讓ThisEscape構建完成再發布出去就可以了。java并發編程實戰的提到私有構造函數+公共的工廠方法解決可能逸出的問題。
public class ThisEscape { private final EventListener listener; private ThisEscape(){ listener = new EventListener(){ public void onEvent(Event e){ doSomething(e) } }; } public static ThisEscape newInstance(EventSource source){ ThisEscape thisEscape = new ThisEscape(); source.registerListener(thisEscape.listener); return thisEscape; } }
同理在構造函數可以新建線程,當不要start()。start()的話this被新線程共享。下面代碼就是錯誤的:
public class ThisEscape { private Thread thread; public ThisEscape(){ thread = new Thread(){ public void run(){ ... } }; thread.start(); //可以在構造函數中new Thread 但是不要start } public static void main(String[] args){ ThisEscape a = new ThisEscape(); } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69062.html
摘要:每個會緩存主存的共享變量,從而提高處理效率。為當前緩存行加入緩存一致性協議。任何修改,其他線程是可見的。修飾的變量還是會緩存的,只是通過一系列處理保證了所有線程看到這個變量的值是一致的 java并發編程實戰對volatile的解釋就是:當一個域聲明為valatile類型后,編譯器與運行時會監視這個變量:它是共享的,而且對它的操作不會與其他的內存操作一起被重排序。volatile變量不會...
摘要:是需要我們去處理很多事情,為了防止多線程給我們帶來的安全和性能的問題下面就來簡單總結一下我們需要哪些知識點來解決多線程遇到的問題。 前言 不小心就鴿了幾天沒有更新了,這個星期回家咯。在學校的日子要努力一點才行! 只有光頭才能變強 回顧前面: 多線程三分鐘就可以入個門了! Thread源碼剖析 本文章的知識主要參考《Java并發編程實戰》這本書的前4章,這本書的前4章都是講解并發的基...
摘要:發布的對象內部狀態可能會破壞封裝性,使程序難以維持不變性條件。不變性線程安全性是不可變對象的固有屬性之一。可變對象必須通過安全方式來發布,并且必須是線程安全的或者有某個鎖保護起來。 線程的優缺點 線程是系統調度的基本單位。線程如果使用得當,可以有效地降低程序的開發和維護等成本,同時提升復雜應用程序的性能。多線程程序可以通過提高處理器資源的利用率來提升系統的吞吐率。與此同時,在線程的使用...
摘要:對象的共享上一章介紹了如何通過同步來避免多個線程在同一時刻訪問相同的數據,而本章將介紹如何共享和發布對象,從而使它們能夠安全地由多個線程同時訪問。為了確保多個線程的之間對內存寫入操作的可見性,必須使用同步機制。 對象的共享 上一章介紹了如何通過同步來避免多個線程在同一時刻訪問相同的數據,而本章將介紹如何共享和發布對象,從而使它們能夠安全地由多個線程同時訪問。 列同步代碼塊和同步方法可...
摘要:當某個不應該發布的對象被發布時,這種情況被稱為逸出。線程安全共享線程安全的對象在其內部實現同步,因此多線程可以通過對象的公有接口來進行訪問而不需要進一步的同步。 前言 本系列博客是對《Java并發編程實戰》的一點總結,本篇主要講解以下幾個內容,內容會比較枯燥。可能大家看標題不能能直觀的感受出到底什么意思,這就是專業術語,哈哈,解釋下,術語(terminology)是在特定學科領域用...
閱讀 830·2021-09-22 15:18
閱讀 1181·2021-09-09 09:33
閱讀 2758·2019-08-30 10:56
閱讀 1184·2019-08-29 16:30
閱讀 1488·2019-08-29 13:02
閱讀 1458·2019-08-26 13:55
閱讀 1643·2019-08-26 13:41
閱讀 1941·2019-08-26 11:56