網站首頁 編程語言 正文
一、簡介
Lock關鍵字是Monitor的一種替換用法,lock在IL代碼中會被翻譯成Monitor.?
lock (obj)
{
//代碼段
}
//就等同于
Monitor.Enter(obj);
//代碼段
Monitor.Exit(obj);
Monitor的常用屬性和方法:
- Enter(Object) 在指定對象上獲取排他鎖。
- Exit(Object) 釋放指定對象上的排他鎖。
- Pulse 通知等待隊列中的線程鎖定對象狀態的更改。
- PulseAll 通知所有的等待線程對象狀態的更改。
- TryEnter(Object) 試圖獲取指定對象的排他鎖。
- TryEnter(Object, Boolean) 嘗試獲取指定對象上的排他鎖,并自動設置一個值,指示是否得到了該鎖。
- Wait(Object) 釋放對象上的鎖并阻止當前線程,直到它重新獲取該鎖。
常用的方法有兩個
- Monitor.Enter(object)方法是獲取鎖
- Monitor.Exit(object)方法是釋放鎖
這就是Monitor最常用的兩個方法,在使用過程中為了避免獲取鎖之后因為異常,致鎖無法釋放,所以需要在try{} catch(){}之后的finally{}結構體中釋放鎖(Monitor.Exit())。
二、代碼
1.Enter(Object)案例
Enter(Object)的用法很簡單,看代碼
class Program
{
static void Main(string[] args)
{
Thread threadA = new Thread(ThreadMethod);
threadA.Name = "A";
Thread threadB = new Thread(ThreadMethod);
threadB.Name = "B";
threadA.Start();
threadB.Start();
Thread.CurrentThread.Name = "C";
ThreadMethod();
Console.ReadKey();
}
static object obj = new object();
public static void ThreadMethod()
{
Monitor.Enter(obj); //Monitor.Enter(obj) 鎖定對象
try
{
for (int i = 1; i <= 10; i++)
{
Console.Write(Thread.CurrentThread.Name + ":" + i + "\t");
}
Console.WriteLine();
}
catch (Exception ex)
{
}
finally
{
Monitor.Exit(obj); // Monitor.Exit(obj); 釋放鎖定對象
}
}
}
執行結果:
2.TryEnter(Object)和TryEnter()案例
TryEnter(Object)和TryEnter()方法在嘗試獲取一個對象上的顯式鎖方面和 Enter()方法類似。然而,它不像Enter()方法那樣會阻塞執行。如果線程成功進入關鍵區域那么TryEnter()方法會返回true. 和試圖獲取指定對象的排他鎖。看下面代碼演示:
class Program
{
static void Main(string[] args)
{
Thread threadA = new Thread(ThreadMethod);
threadA.Name = "A";
Thread threadB = new Thread(ThreadMethod);
threadB.Name = "B";
threadA.Start();
threadB.Start();
Thread.CurrentThread.Name = "C";
ThreadMethod();
Console.ReadKey();
}
static object obj = new object();
public static void ThreadMethod()
{
bool flag = Monitor.TryEnter(obj, 1000);
//設置1S的超時時間,如果在1S之內沒有獲得同步鎖,則返回false
//上面的代碼設置了鎖定超時時間為1秒,也就是說:
//如果在1秒中后,lockObj還未被解鎖,TryEntry方法就會返回false,如果在1秒之內,lockObj被解鎖,TryEntry返回true。我們可以使用這種方法來避免死鎖
try
{
if (flag)
{
for (int i = 1; i <= 10; i++)
{
Console.Write(Thread.CurrentThread.Name + ":" + i + "\t");
}
Console.WriteLine();
}
}
catch (Exception ex)
{
}
finally
{
if (flag)
Monitor.Exit(obj); // Monitor.Exit(obj); 釋放鎖定對象
}
}
}
執行結果:
通過Monitor.TryEnter(monster, 1000),該方法也能夠避免死鎖的發生,我們上面的例子用到的是該方法的重載,Monitor.TryEnter(Object,Int32)。
三、總結
為了能避免多線程死鎖的發生,盡量用TryEnter(Object)和TryEnter()方法在嘗試獲取一個對象上的顯式鎖。
原文鏈接:https://www.cnblogs.com/wml-it/p/14822252.html
相關推薦
- 2022-12-24 Go中函數的使用細節與注意事項詳解_Golang
- 2022-07-22 Mybatis為實體類自定義別名的兩種方式
- 2022-10-29 C++ 模板的顯式具體化
- 2022-10-05 使用?Swift?Package?插件生成代碼的示例詳解_Swift
- 2022-11-29 如果服務器出現內存泄漏,堆內存緩慢上漲,一段時間后觸發了fullGc,如何快速定位?
- 2022-09-22 springboot整合log4j2報錯Unexpected filename extension
- 2022-05-09 shell腳本編程Makefile的使用_linux shell
- 2022-11-05 C/C++讀取大文件數據方式詳細講解_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支