|NO.Z.00105|——————————|BigDataEnd|——|Java&多執行緒.V17|------------------------------------------------|Java.v17|使用Lock鎖|實現執行緒同步|
阿新 • • 發佈:2022-04-04
[BigDataJava:Java&多執行緒.V17] [BigDataJava.核心類庫] [|章節三|多執行緒|使用Lock鎖實現執行緒同步|]
一、使用Lock(鎖)實現執行緒同步
二、常用的方法### --- 基本概念 ——> 從Java5開始提供了更強大的執行緒同步機制—使用顯式定義的同步鎖物件來實現。 ——> java.util.concurrent.locks.Lock介面是控制多個執行緒對共享資源進行訪問的工具。 ——> 該介面的主要實現類是ReentrantLock類,該類擁有與synchronized相同的併發性, ——> 在以後的執行緒安全控制中,經常使用ReentrantLock類顯式加鎖和釋放鎖。
方法宣告 | 功能介紹 |
ReentrantLock() | 使用無參方式構造物件 |
void lock() | 獲取鎖 |
void unlock() | 釋放鎖 |
四、程式設計程式碼### --- 與synchronized方式的比較 ——> Lock是顯式鎖,需要手動實現開啟和關閉操作,而synchronized是隱式鎖, ——> 執行鎖定程式碼後自動釋放。 ——> Lock只有同步程式碼塊方式的鎖,而synchronized有同步程式碼塊方式和同步方法兩種鎖。 ——> 使用Lock鎖方式時,Java虛擬機器將花費較少的時間來排程執行緒,因此效能更好。
五、編譯列印package com.yanqi.task18; import java.util.concurrent.locks.ReentrantLock; public class AccountRunnableTest implements Runnable { private int balance; // 用於描述賬戶的餘額 private Demo dm = new Demo(); private ReentrantLock lock = new ReentrantLock(); // 準備了一把鎖 public AccountRunnableTest() { } public AccountRunnableTest(int balance) { this.balance = balance; } public int getBalance() { return balance; } public void setBalance(int balance) { this.balance = balance; } @Override public /*synchronized*/ void run() { // 開始加鎖 lock.lock(); // 由原始碼可知:最終是account物件來呼叫run方法,因此當前正在呼叫的物件就是account,也就是說this就是account //synchronized (this) { // ok System.out.println("執行緒" + Thread.currentThread().getName() + "已啟動..."); //synchronized (dm) { // ok //synchronized (new Demo()) { // 鎖不住 要求必須是同一個物件 // 1.模擬從後臺查詢賬戶餘額的過程 int temp = getBalance(); // temp = 1000 temp = 1000 // 2.模擬取款200元的過程 if (temp >= 200) { System.out.println("正在出鈔,請稍後..."); temp -= 200; // temp = 800 temp = 800 try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("請取走您的鈔票!"); } else { System.out.println("餘額不足,請核對您的賬戶餘額!"); } // 3.模擬將最新的賬戶餘額寫入到後臺 setBalance(temp); // balance = 800 balance = 800 //} lock.unlock(); // 實現解鎖 } public static void main(String[] args) { AccountRunnableTest account = new AccountRunnableTest(1000); //AccountRunnableTest account2 = new AccountRunnableTest(1000); Thread t1 = new Thread(account); Thread t2 = new Thread(account); //Thread t2 = new Thread(account2); t1.start(); t2.start(); System.out.println("主執行緒開始等待..."); try { t1.join(); //t2.start(); // 也就是等待執行緒一取款操作結束後再啟動執行緒二 t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("最終的賬戶餘額為:" + account.getBalance()); // 600 800 } } class Demo{}
D:\JAVA\jdk-11.0.2\bin\java.exe "-javaagent:D:\IntelliJIDEA\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=51182:D:\IntelliJIDEA\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath E:\NO.Z.10000——javaproject\NO.H.00001.javase\javase\out\production\javase com.yanqi.task18.AccountThreadTest
主執行緒開始等待...
執行緒Thread-0已啟動...
正在出鈔,請稍後...
請取走您的鈔票!
執行緒Thread-1已啟動...
正在出鈔,請稍後...
請取走您的鈔票!
最終的賬戶餘額為:1000
Process finished with exit code 0
===============================END===============================
Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart ——W.S.Landor
來自為知筆記(Wiz)