Servlet學習筆記 Servlet學習 學習視頻為:https://www.bilibili.com/video/BV1Ta4y1H7Vc IDEA的使用 IDEA的簡介 IDEA 全稱 IntelliJ IDEA,由JetBrains公司開發,是java編程語言開發的集成環境。在業界被公認為最 ...
轉自:
http://www.java265.com/JavaJingYan/202205/16536185653533.html
下文筆者講述工作中避免死鎖的方法分享,如下所示:
1.設置超時時間
Lock的tryLock(Long timeout,TimeUnit unit) 設置獲取鎖的時間,如果達到這個時間還沒有獲取到鎖,就回退 synchronized 不具備嘗試鎖的能力 獲取不到鎖的,也就是獲取失敗,我們進行日誌記錄,郵件提醒,重啟伺服器
/** * 用tryLock來避免死鎖 */ public class TryLockDeadlock implements Runnable{ int flag = 1; static Lock lock1 = new ReentrantLock(); static Lock lock2 = new ReentrantLock(); public static void main(String[] args) { TryLockDeadlock deadlock1 = new TryLockDeadlock(); TryLockDeadlock deadlock2 = new TryLockDeadlock(); deadlock1.flag = 1; deadlock1.flag = 0; new Thread(deadlock1).start(); new Thread(deadlock2).start(); } @Override public void run() { for (int i = 0; i < 100; i++) { if(flag == 1){ try { if(lock1.tryLock(300, TimeUnit.MILLISECONDS)){ System.out.println("線程1獲取到了鎖1"); Thread.sleep(new Random().nextInt(10)); if(lock2.tryLock(300, TimeUnit.MILLISECONDS)){ System.out.println("線程1獲取到了鎖2"); lock1.unlock(); lock2.unlock(); break; }else{ System.out.println("線程1獲取第二把鎖的時候,失敗,已經重試"); lock1.unlock(); Thread.sleep(new Random().nextInt(10)); } }else{ System.out.println("線程1獲取鎖1失敗,已經重試"); } } catch (InterruptedException e) { e.printStackTrace(); } } if(flag == 0){ try { if(lock2.tryLock(3000, TimeUnit.MILLISECONDS)){ System.out.println("線程2獲取到了鎖2"); Thread.sleep(new Random().nextInt(1000)); if(lock1.tryLock(3000, TimeUnit.MILLISECONDS)){ System.out.println("線程2獲取到了鎖1"); lock2.unlock(); lock1.unlock(); break; }else{ System.out.println("線程2獲取第1把鎖的時候,失敗,已經重試"); lock2.unlock(); Thread.sleep(new Random().nextInt(1000)); } }else{ System.out.println("線程2獲取鎖2失敗,已經重試"); } } catch (InterruptedException e) { e.printStackTrace(); } } } } }
2.多使用併發類不要使用自己設計的鎖
ConcurrentHashMap(併發場景,並需要map優先選擇)、ConcurrentLinkedQueue、AtomicBoolean等
3.儘量降低鎖的使用粒度:用不同的鎖而不是一個鎖
4.能使用同步代碼塊,就不適用同步方法:自己指定鎖對象
5.給自己定義的線程起一個有意義的名稱:排錯方便
6.避免鎖的嵌套
7.分配資源前先看能不能收回來:銀行家演算法