重入鎖ReentrantLock

什麼是可重入?

可重入鎖指的是可重複可遞歸調用的鎖,在外層使用鎖之後,在內層仍然可以使用,並且不發生死鎖(前提得是同一個對象或者class),這樣的鎖就叫做可重入鎖。ReentrantLock和synchronized都是可重入鎖。

一.在講解之前先介紹一下synchronized

synchronized是java內置的關鍵字,獲取和釋放鎖由JVM實現,非常方便。然而synchronized也有一定的侷限性。

  1. 當線程嘗試獲取鎖的時候,如果獲取不到鎖會一直阻塞。
  2. 如果獲取鎖的線程進入休眠或者阻塞,除非當前線程異常,否則其他線程嘗試獲取鎖必須一直等待

JDK1.5之後發佈,加入了concurrent包。包內提供了Lock類,用來擴展的加鎖功能。Lock彌補了synchronized的侷限,提供了更加細粒度的加鎖功能。

二.ReentrantLock介紹

Lock lock = new ReentrantLock();

Lock是一個接口,ReentrantLock鎖是lock的一個實現

Lock接口的幾個方法的總體描述

/**
 * 嘗試鎖
 */
package concurrent.t03;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Test_02 {
	Lock lock = new ReentrantLock();
	
	void m1(){
		try{
			lock.lock();
			for(int i = 0; i < 10; i++){
				TimeUnit.SECONDS.sleep(1);
				System.out.println("m1() method " + i);
			}
            //在lock和unlock之間可以調用m1()方法(遞歸調用),俗稱可重入。
            // m1();
		}catch(InterruptedException e){
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
	}
	
	void m2(){
		boolean isLocked = false;
		try{
			// 嘗試鎖, 如果有鎖,無法獲取鎖標記,返回false。
			// 如果獲取鎖標記,返回true
			// isLocked = lock.tryLock();
			
			// 阻塞嘗試鎖,阻塞參數代表的時長,嘗試獲取鎖標記。
			// 如果超時,不等待。直接返回。
			isLocked = lock.tryLock(5, TimeUnit.SECONDS); 
			
			if(isLocked){
				System.out.println("m2() method synchronized");
			}else{
				System.out.println("m2() method unsynchronized");
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if(isLocked){
				// 嘗試鎖在解除鎖標記的時候,一定要判斷是否獲取到鎖標記。
				// 如果當前線程沒有獲取到鎖標記,會拋出異常。
				lock.unlock();
			}
		}
	}
	
	public static void main(String[] args) {
		final Test_02 t = new Test_02();
		new Thread(new Runnable() {
			@Override
			public void run() {
				t.m1();
			}
		}).start();
		try {
			TimeUnit.SECONDS.sleep(1);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		new Thread(new Runnable() {
			@Override
			public void run() {
				t.m2();
			}
		}).start();
	}
}

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章