1. 程式人生 > >淺談java執行緒安全

淺談java執行緒安全

在瞭解執行緒安全之前,有必要談談執行緒的工作原理,我本人的理解是這樣的:

jvm中有主存,Java中所有變數都儲存在主存中,對於所有執行緒都是共享的.同時每個執行緒擁有自己獨有的工作記憶體,當一個執行緒對一個變數進行操作時,都要在自己的工作記憶體中建立該變數的一個副本,操作完之後再寫入主記憶體.執行緒之間無法相互直接訪問,變數傳遞均需要通過主存完成.

因此多個執行緒同時操作同一個變數時,就可能會出現不可預知的結果.

解決該問題我們第一個想到的就是synchronized關鍵字,synchronized具有原子性和可見性兩個重要的特性.

1.原子性

所謂原子性就是當一個執行緒對一份程式碼進行操作時,不會被執行緒排程機制打斷,一旦開始操作,就一直執行到結束.也就是說當該執行緒對一段程式碼進行操作時,不會有其他執行緒來打斷它.

2.可見性

可見性就是指當一個執行緒修改了執行緒共享變數的值,其它執行緒能夠立即得知這個修改.很明顯單個執行緒在各自獨立工作記憶體修改共享變數的副本後,會將新值同步回主記憶體,這樣其他執行緒再次訪問主存就能感知到共享變數的變化.就起到了可見性作用(後面會提到volatile關鍵字,用於保證變數的可見性).
synchronized的作用是建立一個監視器(monitor),也就是執行緒所持有的鎖,當執行緒操作一份程式碼時,通過加鎖來實現執行緒安全,每個執行緒只有獲得鎖之後,執行完"載入到工作記憶體->操作->寫入到主存"的過程,才會釋放鎖.
所以執行緒不安全就是如果多執行緒訪問同一份程式碼,得不到我們預期的結果.執行緒安全的實現依靠執行緒同步.
下面探討synchronized關鍵字的用法:
synchronized可修飾普通方法,靜態方法,或者程式碼塊.
每個java物件都可以用做一個實現同步的鎖,這些鎖稱為內建鎖.同一個物件的鎖最短只有一個執行緒能夠獲得該鎖.
下面分析如下程式碼:

synchronized修飾方法:
1.物件鎖的synchronized修飾方法和程式碼塊.

public synchronized void test1(){
    操作.....
}

public void test2{
    synchronized(this){
	程式碼塊...
    }
}
第一種方法預設鎖為當前物件,第二個方法用了同步程式碼塊方式,傳入的物件例項是this,表明是當前物件,所以兩個同步程式碼所需要獲得的物件鎖都是同一個物件鎖.
當然第二個方法也可傳入其他物件的例項,用於不同的物件鎖.
2.類鎖的synchronized修飾(靜態)方法和程式碼塊:
public static synchronized void test1(){
    操作.....
}  

public void test2{
    synchronized(TestSynchronized.class){
	程式碼塊...
    }
}
因為類鎖只是一個抽象出來的概念,只是為了區別靜態方法的特點,因為靜態方法是所有物件例項共用的,所以對應著synchronized修飾的靜態方法的鎖也是唯一的,所以抽象出來個類鎖.


類鎖和物件鎖是兩個不一樣的鎖,控制著不同的區域,它們是互不干擾的。同樣,執行緒獲得物件鎖的同時,也可以獲得該類鎖,即同時獲得兩個鎖,這是允許的。


相關推薦

java執行安全

在瞭解執行緒安全之前,有必要談談執行緒的工作原理,我本人的理解是這樣的: jvm中有主存,Java中所有變數都儲存在主存中,對於所有執行緒都是共享的.同時每個執行緒擁有自己獨有的工作記憶體,當一個執行緒對一個變數進行操作時,都要在自己的工作記憶體中建立該變數的一個副本,操作

執行安全問題

下面我們還是用看電影賣票的案例來談一談多執行緒安全的問題。 方案一:使用同步程式碼塊 //實現賣票案例 /* 賣票案例出現執行緒安全問題 解決方案一:使用同步程式碼塊 格式: synchronized(鎖物件){ 可能會出現執行緒安全問題的程式

java執行池(基於jdk1.8)

多執行緒讓程式世界豐富多彩,也讓其錯綜複雜。對於執行緒的建立和銷燬成了一筆不小的開銷,為了減少這些開銷,出現了執行緒池。執行緒池對執行緒進行管理,對於需要使用多執行緒的你來說,只需要把你的任務丟給執行緒池就可以了。當你把任務丟給執行緒池的時候,它是如何處理的呢?

Java執行狀態轉換及控制

執行緒的狀態(系統層面)   一個執行緒被建立後就進入了執行緒的生命週期。線上程的生命週期中,共包括新建(New)、就緒(Runnable)、執行(Running)、阻塞(Blocked)和死亡(Dead)這五種狀態。當執行緒啟動以後,CPU需要在多個執行緒之間切換,所以執行緒也會隨之在執行、阻塞、就緒這幾種

Java執行安全

執行緒不安全的類: HashMap LinkedHashMap TreeMap ArrayList LinkedList HashSet TreeSet LinkedHashSet StringBuilder 執行緒安全的類: ConcurrentHashMap Hasht

Java執行安全與多執行開發

網際網路上充斥著對Java多執行緒程式設計的介紹,每篇文章都從不同的角度介紹並總結了該領域的內容。但大部分文章都沒有說明多執行緒的實現本質,沒能讓開發者真正“過癮”。 從Java的執行緒安全鼻祖內建鎖介紹開始,讓你瞭解內建鎖的實現邏輯和原理以及引發的效能問題,接著說明了Java多執行緒程式設計中鎖的存在是為

java執行

      在專案中一般使用執行緒池來進行非同步、多執行緒操作,但是在建立執行緒池時也會又各種情況,比如說使用jdk自帶的Executors,在某些情況下會出現一些問題。 如上面提示所說,使用Executors在實際專案中執行的確會有各種風險。 那麼我們就需要手動

java執行安全問題

併發搶票過程中,如果不加同步鎖,就會出現執行緒不安全問題,導致程式碼執行結果出現嚴重問題。另外同一個執行緒啟動多次是不允許的。package sx.test.thread;public class TicketDemo {public static void main(Str

Java-執行安全

Java-執行緒安全 0x01 什麼是執行緒安全 執行緒安全是針對某個物件來說,如果當多執行緒訪問此物件時,不用再用額外方式如同步鎖等,總能執行獲得正確結果,那就可以說這個物件程式碼執行緒安全。 0x02 Java中的執行緒安全 Java中執行緒安全強度由強到弱是: 不可

C++執行安全容器的設計

    最近看到一本書,《C++併發程式設計實戰》,[美] Anthony Williams 著,裡面有談及執行緒安全容器的設計及實現程式碼,本人覺得這樣的設計有點問題,問題還是比較明顯的,寫在這裡,供讀者自己思考吧。      關於程式碼,可以在這裡下載: https:/

關於java執行安全問題

執行緒:負責一個程序中的程式碼執行。執行緒是程序中的一個執行路徑。 執行緒安全問題出現的根本原因:1. 存在著兩個或者兩個以上的執行緒。2. 多個執行緒共享了著一個資源, 而且操作資源的程式碼有多句。 執行緒安全問題的解決方案:1. 使用同步程式碼塊格式:synchroni

Java執行安全佇列Queue

在Java多執行緒應用中,佇列的使用率很高,多數生產消費模型的首選資料結構就是佇列。Java提供的執行緒安全的Queue可以分為阻塞佇列和非阻塞佇列,其中阻塞佇列的典型例子是BlockingQueue,非阻塞佇列的典型例子是ConcurrentLinkedQue

執行池的理解

1、首先由幾個介面和類的關係是需要先說明的: extends   implementsextends Executor(介面)----------------->ExecutorService(介面)------------------->AbstractExe

java執行安全之併發Queue(十三)

併發Queue        在併發的佇列上jdk提供了兩套實現,一個是以ConcurrentLinkedQueue為代表的高效能佇列,一個是以BlockingQueue介面為代表的阻塞佇列,無論在那種都繼承自Queue。 如圖繼承Queue共有二十四個:

java 執行安全的全域性計數器-AtomicInteger原子操作類

首先 , 測試一下正常程式碼 public class Test1 { public static int count = 0; public static void main(String[] args) { for (int i =

執行之鎖的機制

Java中鎖的機制 synchronized–Java語言的關鍵字,當它用來修飾一個方法或者一個程式碼塊的時候,能夠保證在同一時刻最多隻有一個執行緒執行該段程式碼。 當兩個併發執行緒訪問同一個物件Object中的這個synchronized同步程式碼塊時,

java執行安全之synchronized鎖重入及出現異常鎖自動釋放(五)

科技快訊       11月16日下午訊息,以“Bring AI to Life”為主題的2017百度世界大會今天在北京國貿大酒店和北京嘉裡大酒店舉行。愛奇藝創始人兼CEO龔宇在大會上發表了主題為“愛奇藝·更懂娛樂”的主題演講,龔宇表示愛奇藝對於科技的重視與百

java執行安全的實現方法_筆記

閱讀《深入理解java虛擬機器》後的閱讀筆記。1、 互斥同步同步時指在多個執行緒併發訪問共享資料時,保證共享資料在同一個時刻只被一個(或者是一些,使用訊號量的時候)執行緒使用。而互斥是實現同步的一種手段,臨界區,互斥量和訊號量都是主要的互斥實現方式。  1.1 在java中最

java執行安全之併發Queue

關閉 原 java執行緒安全之併發Queue(十三) 2017年11月19日 23:40:23 小彬彬~ 閱讀數:12092更多

java執行安全的容器有哪些?

同步容器類:使用了synchronized 1.Vector 2.HashTable 併發容器: 3.ConcurrentHashMap:分段 4.CopyOnWriteArrayList:寫時複製 5.CopyOnWriteArraySet:寫時複製 Queue: 6.C