java多線程加鎖的簡單處理辦法

    當對數據修改時,若是兩個線程同時去修改同一條數據,這樣產生的結果就不是咱們預期的結果。這時候就須要對修改操做進行加鎖,讓jvm裏同一時刻只能有一個線程可以執行修改方法。java

    下面是一個未加鎖的修改方法:   多線程

public void update(Entry entry){
    dao.update(entry);
}

    如今討論下傳統的加鎖方法。咱們知道每個對象都隱含了一個鎖,那就是對象自己。咱們能夠在方法體上加上同步字段synchronizedjvm

public synchronized void update(Entry entry){
    dao.update(entry);
}

但若是方法裏代碼不少,那麼加在方法上會鎖住不少代碼,咱們可使用同步塊性能

public void update(Entry entry){
    dobefore();
    synchronized(this){
        dao.update(entry);
    }
    doend(); 
}

    而須要注意的是若是一個類中存在多個同步方法,那麼全部同步方法的鎖都是對象自己,也就是說當執行update的時候,別的線程不只不能執行update連類中別的同步方法也不能使用。固然也可使用一點技巧去規避這個問題,好比使用其餘鎖。this

    咱們這篇博客說得不是上面的方法,而是另一個位於java.util.concurrent.locks包下的ReentrantLock。spa

    官方是這麼說的:線程

    一個可重入的互斥鎖 Lock,它具備與使用 synchronized 方法和語句所訪問的隱式監視器鎖相同的一些基本行爲和語義,但功能更強大。
    ReentrantLock 將由最近成功得到鎖,而且尚未釋放該鎖的線程所擁有。當鎖沒有被另外一個線程所擁有時,調用 lock 的線程將成功獲取該鎖並返回。若是當前線程已經擁有該鎖,此方法將當即返回。可使用 isHeldByCurrentThread() 和 getHoldCount() 方法來檢查此狀況是否發生。
    此類的構造方法接受一個可選的公平 參數。當設置爲 true 時,在多個線程的爭用下,這些鎖傾向於將訪問權授予等待時間最長的線程。不然此鎖將沒法保證任何特定訪問順序。與採用默認設置(使用不公平鎖)相比,使用公平鎖的程序在許多線程訪問時表現爲很低的整體吞吐量(即速度很慢,經常極其慢),可是在得到鎖和保證鎖分配的均衡性時差別較小。不過要注意的是,公平鎖不能保證線程調度的公平性。所以,使用公平鎖的衆多線程中的一員可能得到多倍的成功機會,這種狀況發生在其餘活動線程沒有被處理而且目前並未持有鎖時。還要注意的是,未定時的 tryLock 方法並無使用公平設置。由於即便其餘線程正在等待,只要該鎖是可用的,此方法就能夠得到成功。code

    使用它也很簡單,你能夠用以下結構來使用他:   對象

class X {
   private final ReentrantLock lock = new ReentrantLock();
   // ...

   public void m() { 
     lock.lock();  // block until condition holds
     try {
       // ... method body
     } finally {
       lock.unlock()
     }
   }
 }

    經常使用的方法就如上面所說的同樣,lock和unlock   接口

lock
public void lock()
獲取鎖。
若是該鎖沒有被另外一個線程保持,則獲取該鎖並當即返回,將鎖的保持計數設置爲 1。
若是當前線程已經保持該鎖,則將保持計數加 1,而且該方法當即返回。
若是該鎖被另外一個線程保持,則出於線程調度的目的,禁用當前線程,而且在得到鎖以前,該線程將一直處於休眠狀態,此時鎖保持計數被設置爲 1。
指定者:
接口 Lock 中的 
lock

unlock
public void unlock()
試圖釋放此鎖。
若是當前線程是此鎖全部者,則將保持計數減 1。若是保持計數如今爲 0,則釋放該鎖。若是當前線程不是此鎖的持有者,則拋出 IllegalMonitorStateException。
指定者:
接口 Lock 中的 
unlock
拋出:
IllegalMonitorStateException - 若是當前線程沒有保持此鎖

    固然他還有別的不少方法,須要的話能夠本身去看看。

    對比synchronized這個鎖是獨立的,在一個類中多個同步塊之間都是獨立的,互不影響。最後說一句,由於同步塊會讓一段代碼同一時刻只能有一個線程使用,多線程同時訪問,一個使用其餘都是等待狀態,那麼就存在一個性能問題。若是理解原子性,又那麼牛X,利用原子性寫出避免同步的免鎖代碼,什麼synchronized啊,ReentrantLock啊,都是浮雲。

相關文章
相關標籤/搜索