Java執行緒學習之讀寫鎖
阿新 • • 發佈:2022-04-22
讀寫鎖:
因為讀寫鎖分為讀鎖和寫鎖,讀因為不會對資料造成改變,所以兩個或多個執行緒的讀之間不需要新增鎖。而寫鎖不同,因為寫對資料會進行改變,所以 寫與寫之間,讀與寫之間都需要加鎖控制。而在重入鎖中,讀與讀之間也會使用互斥鎖,造成等待時間延長。這樣的話讀寫鎖的使用場景也就出來了,讀寫鎖適用於讀操作遠比寫操作的次數,這樣可以提升系統性能。
例子:
package com.example.demo.bingfa; import java.util.Random; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class ReadWriteLockDemo { public static Lock lock = new ReentrantLock(); public static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); private static Lock readLock = readWriteLock.readLock(); public static Lock writeLock = readWriteLock.writeLock(); private int value; public static long readTime; public static long writeTime; public static void main(String[] args) throws InterruptedException { final ReadWriteLockDemo demo = new ReadWriteLockDemo(); Runnable readRunnale = new Runnable() { @Override public void run() { try { //此處傳入的是讀鎖,如果換成重入鎖,執行結果會變化很大 demo.handleRead(readLock); } catch (Exception e) { e.printStackTrace(); } } }; Runnable writeRunnale = new Runnable() { @Override public void run() { try { //此處傳入的是寫鎖,如果換成重入鎖,將會改變 demo.handleWrite(writeLock, new Random().nextInt()); } catch (Exception e) { e.printStackTrace(); } } }; long start=System.currentTimeMillis(); for (int i = 0; i < 10; i++) { new Thread(readRunnale).start(); } for (int i = 10; i < 20; i++) { new Thread(writeRunnale).start(); } //讓主執行緒等待一段時間,確保子執行緒均已執行完畢 Thread.sleep(30000); System.out.println("讀操作耗時:" +(readTime-start)+" 寫操作耗時"+(writeTime-start)); } /** * 寫操作處理,因為寫與寫之間是互斥的 ,所以每個寫的執行緒都需要等待獲得鎖 * @param writeLock * @param i * @throws InterruptedException */ private void handleWrite(Lock writeLock, int i) throws InterruptedException { try { writeLock.lock(); Thread.sleep(1000); value = i; } finally { writeLock.unlock(); writeTime=System.currentTimeMillis(); } } /** * 因為讀與讀之間不是互斥的所以讀與讀是可以並行的 * @param readLock * @return * @throws InterruptedException */ private int handleRead(Lock readLock) throws InterruptedException { try { readLock.lock(); Thread.sleep(1000); return value; } finally { readLock.unlock(); readTime=System.currentTimeMillis(); } } }