大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 hot資訊 告訴你什么是Java中的可重入鎖

告訴你什么是Java中的可重入鎖

更新時間:2022-09-08 11:12:49 來源:動力節點 瀏覽1649次

什么是可重入鎖?

相信大家對Java ReentrantLock使用都有了一定的了解,ReentrantLock 類實現了 Lock 接口,并在訪問共享資源時為方法提供同步。操作共享資源的代碼被鎖定和解鎖方法的調用包圍。這為當前工作線程提供了一個鎖定,并阻止了所有其他試圖鎖定共享資源的線程。

顧名思義,ReentrantLock 允許線程多次進入資源鎖。當線程第一次進入鎖時,保持計數設置為 1。在解鎖之前,線程可以重新進入鎖,每次保持計數加一。對于每個解鎖請求,保持計數減 1,當保持計數為 0 時,資源被解鎖。

可重入鎖還提供了一個公平參數,通過該參數,鎖將遵循鎖請求的順序,即在線程解鎖資源后,鎖將轉到等待時間最長的線程。這種公平模式是通過將 true 傳遞給鎖的構造函數來設置的。

這些鎖的使用方式如下:

public void some_method()
{
		reentrantlock.lock();
		try
		{
			//Do some work
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			reentrantlock.unlock();
		}		
}

總是在 finally 塊中調用解鎖語句,以確保即使在方法體(try 塊)中拋出異常也能釋放鎖。

ReentrantLock() 方法

lock():調用 lock() 方法將保持計數加 1,如果共享資源最初是空閑的,則將鎖分配給線程。

unlock():調用unlock()方法將持有計數減1。當這個計數達到零時,資源被釋放。

tryLock():如果資源未被任何其他線程持有,則調用 tryLock() 返回 true,并且持有計數加 1。如果資源不是空閑的,則該方法返回 false,線程不會被阻塞,而是退出。

tryLock(long timeout, TimeUnit unit):根據方法,線程在退出前等待方法參數定義的一定時間段來獲取資源的鎖。

lockInterruptibly():如果資源空閑,則此方法獲取鎖,同時允許線程在獲取資源時被其他線程中斷。意思是如果當前線程正在等待鎖,但是其他線程請求鎖,那么當前線程將被中斷并立即返回而不獲取鎖。

getHoldCount():此方法返回資源上持有的鎖的數量。

isHeldByCurrentThread():如果當前線程持有資源的鎖,則此方法返回 true。

ReentrantLock() 示例

在下面的教程中,我們將看一個可重入鎖的基本示例。

應遵循的步驟

1.創建ReentrantLock的對象

2.創建一個worker(Runnable Object)來執行并將鎖傳遞給對象

3.使用lock()方法獲取共享資源的鎖

4.工作完成后調用unlock()方法釋放鎖

下面是問題陳述的實現:

// Java code to illustrate Reentrant Locks
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantLock;
class worker implements Runnable
{
String name;
ReentrantLock re;
public worker(ReentrantLock rl, String n)
{
	re = rl;
	name = n;
}
public void run()
{
	boolean done = false;
	while (!done)
	{
	//Getting Outer Lock
	boolean ans = re.tryLock();
	// Returns True if lock is free
	if(ans)
	{
		try
		{
		Date d = new Date();
		SimpleDateFormat ft = new SimpleDateFormat("hh:mm:ss");
		System.out.println("task name - "+ name
					+ " outer lock acquired at "
					+ ft.format(d)
					+ " Doing outer work");
		Thread.sleep(1500);
		// Getting Inner Lock
		re.lock();
		try
		{
			d = new Date();
			ft = new SimpleDateFormat("hh:mm:ss");
			System.out.println("task name - "+ name
					+ " inner lock acquired at "
					+ ft.format(d)
					+ " Doing inner work");
			System.out.println("Lock Hold Count - "+ re.getHoldCount());
			Thread.sleep(1500);
		}
		catch(InterruptedException e)
		{
			e.printStackTrace();
		}
		finally
		{
			//Inner lock release
			System.out.println("task name - " + name +
					" releasing inner lock");
			re.unlock();
		}
		System.out.println("Lock Hold Count - " + re.getHoldCount());
		System.out.println("task name - " + name + " work done");
		done = true;
		}
		catch(InterruptedException e)
		{
		e.printStackTrace();
		}
		finally
		{
		//Outer lock release
		System.out.println("task name - " + name +
					" releasing outer lock");
		re.unlock();
		System.out.println("Lock Hold Count - " +
					re.getHoldCount());
		}
	}
	else
	{
		System.out.println("task name - " + name +
					" waiting for lock");
		try
		{
		Thread.sleep(1000);
		}
		catch(InterruptedException e)
		{
		e.printStackTrace();
		}
	}
	}
}
}
public class test
{
static final int MAX_T = 2;
public static void main(String[] args)
{
	ReentrantLock rel = new ReentrantLock();
	ExecutorService pool = Executors.newFixedThreadPool(MAX_T);
	Runnable w1 = new worker(rel, "Job1");
	Runnable w2 = new worker(rel, "Job2");
	Runnable w3 = new worker(rel, "Job3");
	Runnable w4 = new worker(rel, "Job4");
	pool.execute(w1);
	pool.execute(w2);
	pool.execute(w3);
	pool.execute(w4);
	pool.shutdown();
}
}

樣品執行

輸出:
任務名稱 - Job2 等待鎖定
任務名稱 - Job1 外部鎖在 09:49:42 獲取
任務名稱 - Job2 等待鎖定
任務名稱 - Job1 內部鎖在 09:49:44 獲得
鎖定保持計數 - 2
任務名稱 - Job2 等待鎖定
任務名稱 - Job2 等待鎖定
任務名稱 - Job1 釋放內部鎖
鎖定保持計數 - 1
任務名稱 - Job1 完成的工作
任務名稱 - Job1 釋放外部鎖
鎖定保持計數 - 0
任務名稱 - Job3 外部鎖在 09:49:45 獲取
任務名稱 - Job2 等待鎖定
任務名稱 - 在 09:49:47 獲得的 Job3 內部鎖正在做內部工作
鎖定保持計數 - 2
任務名稱 - Job2 等待鎖定
任務名稱 - Job2 等待鎖定
任務名稱 - Job3 釋放內部鎖
鎖定保持計數 - 1
任務名稱 - Job3 完成的工作
任務名稱 - Job3 釋放外鎖
鎖定保持計數 - 0
任務名稱 - Job4 外部鎖在 09:49:48 獲取
任務名稱 - Job2 等待鎖定
任務名稱 - Job4 內部鎖在 09:49:50 獲取
鎖定保持計數 - 2
任務名稱 - Job2 等待鎖定
任務名稱 - Job2 等待鎖定
任務名稱 - Job4 釋放內部鎖
鎖定保持計數 - 1
任務名稱 - Job4 完成的工作
任務名稱 - Job4 釋放外鎖
鎖定保持計數 - 0
任務名稱 - Job2 外部鎖在 09:49:52 獲取
任務名稱 - Job2 內部鎖在 09:49:53 獲取
鎖定保持計數 - 2
任務名稱 - Job2 釋放內部鎖
鎖定保持計數 - 1
任務名稱 - Job2 完成的工作
任務名稱 - Job2 釋放外部鎖
鎖定保持計數 - 0

要點

1.人們可能會忘記在 finally 塊中調用 unlock() 方法,從而導致程序出現錯誤。確保在線程退出之前釋放鎖。

2.用于構造鎖對象的公平參數會降低程序的吞吐量。

ReentrantLock 是同步的更好替代品,它提供了許多 synchronized 沒有提供的功能。然而,這些明顯好處的存在并不足以成為總是喜歡 ReentrantLock 進行同步的充分理由。相反,根據您是否需要 ReentrantLock 提供的靈活性來做出決定。

以上就是關于“告訴你什么是Java中的可重入鎖”的介紹,大家如果對此比較感興趣,想了解更多相關知識,可以關注一下動力節點的Java多線程編程,里面有更豐富的知識等著大家去學習,相信對大家一定會有所幫助的哦。

提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 久久久久久久国产a∨ | 亚洲欧美日韩在线中文一 | 国产成人精品免费久久久久 | 国产成人免费高清在线观看 | 久久99这里精品8国产 | 奇米第四色在线 | 精品一区二区三区四区 | 免费看欧美毛片大片免费看 | 97国产在线观看 | 精品煌色视频网站在线观看 | 久久免费精品 | 中文字幕精品视频 | 亚洲视频999 | 国产目拍亚洲精品一区麻豆 | 四虎影视库 | 久久久久在线视频 | 天天看片日日夜夜 | 97免费观看 | 久久综合影院 | 五月花在线观看播放视频 | 四虎国产精品视频免费看 | 国产精品久久久久影院 | 四虎影院永久免费观看 | 国产区成人综合色在线 | 中文一级国产特级毛片视频 | 97在线公开视频 | 特黄特a级特别特级特毛片 特黄特黄aaaa级毛片免费看 | 国产一区二区三区四区 | 五月婷婷综合网 | 两个人高清视频图片中文字幕 | 亚洲九九视频 | 国产va免费高清在线观看 | 日韩在线一区二区 | 精品国产品香蕉在线观看 | 亚洲精品在线网 | 日本欧美国产精品 | 亚洲国产精品久久久久 | 欧美久久天天综合香蕉伊 | 久草在线国产 | 男女一级毛片 | 老司机深夜影院入口aaaa |