国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java鎖之可重入鎖介紹

2019-11-26 15:21:27
字體:
來源:轉載
供稿:網友

鎖作為并發共享數據,保證一致性的工具,在JAVA平臺有多種實現(如 synchronized 和 ReentrantLock等等 ) 。這些已經寫好提供的鎖為我們開發提供了便利,但是鎖的具體性質以及類型卻很少被提及。本系列文章將分析JAVA下常見的鎖名稱以及特性,為大家答疑解惑。

四、可重入鎖:

本文里面講的是廣義上的可重入鎖,而不是單指JAVA下的ReentrantLock。

可重入鎖,也叫做遞歸鎖,指的是同一線程 外層函數獲得鎖之后 ,內層遞歸函數仍然有獲取該鎖的代碼,但不受影響。
在JAVA環境下 ReentrantLock 和synchronized 都是 可重入鎖。

下面是使用實例:

復制代碼 代碼如下:

public class Test implements Runnable{

 public synchronized void get(){
  System.out.println(Thread.currentThread().getId());
  set();
 }

 public synchronized void set(){
  System.out.println(Thread.currentThread().getId());
 }

 @Override
 public void run() {
  get();
 }
 public static void main(String[] args) {
  Test ss=new Test();
  new Thread(ss).start();
  new Thread(ss).start();
  new Thread(ss).start();
 }
}

兩個例子最后的結果都是正確的,即 同一個線程id被連續輸出兩次。

結果如下:

復制代碼 代碼如下:

Threadid: 8
Threadid: 8
Threadid: 10
Threadid: 10
Threadid: 9
Threadid: 9

可重入鎖最大的作用是避免死鎖。
我們以自旋鎖作為例子。

復制代碼 代碼如下:

public class SpinLock {
 private AtomicReference<Thread> owner =new AtomicReference<>();
 public void lock(){
  Thread current = Thread.currentThread();
  while(!owner.compareAndSet(null, current)){
  }
 }
 public void unlock (){
  Thread current = Thread.currentThread();
  owner.compareAndSet(current, null);
 }
}

對于自旋鎖來說:

1、若有同一線程兩調用lock() ,會導致第二次調用lock位置進行自旋,產生了死鎖
說明這個鎖并不是可重入的。(在lock函數內,應驗證線程是否為已經獲得鎖的線程)
2、若1問題已經解決,當unlock()第一次調用時,就已經將鎖釋放了。實際上不應釋放鎖。
(采用計數次進行統計)

修改之后,如下:

復制代碼 代碼如下:

public class SpinLock1 {
 private AtomicReference<Thread> owner =new AtomicReference<>();
 private int count =0;
 public void lock(){
  Thread current = Thread.currentThread();
  if(current==owner.get()) {
   count++;
   return ;
  }

  while(!owner.compareAndSet(null, current)){

  }
 }
 public void unlock (){
  Thread current = Thread.currentThread();
  if(current==owner.get()){
   if(count!=0){
    count--;
   }else{
    owner.compareAndSet(current, null);
   }

  }

 }
}

該自旋鎖即為可重入鎖。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 进贤县| 富阳市| 竹山县| 新巴尔虎右旗| 略阳县| 玉环县| 墨玉县| 龙口市| 渑池县| 阜平县| 南阳市| 皋兰县| 桦南县| 安远县| 桦甸市| 徐闻县| 阿巴嘎旗| 静海县| 营山县| 富川| 小金县| 正安县| 余庆县| 麦盖提县| 泗水县| 三原县| 关岭| 老河口市| 辉南县| 内乡县| 富民县| 临澧县| 古浪县| 永定县| 团风县| 咸阳市| 东乡县| 腾冲县| 大埔县| 万州区| 浮梁县|