1. 程式人生 > >java多線程---讀寫鎖ReadWriteLock

java多線程---讀寫鎖ReadWriteLock

iter 獲得 throw pan fin class err mem catch

public interface ReadWriteLock

ReadWriteLock 維護了一對相關的鎖,一個用於只讀操作,另一個用於寫入操作。只要沒有 writer,讀取鎖可以由多個 reader 線程同時保持。寫入鎖是獨占的。
public abstract interface ReadWriteLock
{
  public abstract Lock readLock();
  
  public abstract Lock writeLock();
}

訪問約束

read write
read 非阻塞 阻塞
write 阻塞 阻塞

ReentrantReadWriteLock誕生於J·U·C。此後,國人一般稱它為讀寫鎖。人如其名,人如其名,她就是一個可重入鎖,同時她還是一個讀、寫鎖。
ReentrantReadWriteLock實現了ReadWriteLock和Serializable,同時ReadWriteLock跟Lock也沒有繼承關系。
ReentrantReadWriteLock跟ReentrantLock只有朋友關系,她們都是一個可重入鎖。

eg:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockTest implements Runnable{
    private static ReentrantLock rl = new ReentrantLock();
    private static ReentrantReadWriteLock readwriteLock = new
ReentrantReadWriteLock(); private static Lock readLock = readwriteLock.readLock(); private static Lock writeLock = readwriteLock.writeLock(); public void handleRead(Lock lock) throws InterruptedException{ try{ lock.lock(); Thread.sleep(1000); System.out
.println(Thread.currentThread().getName() + " 獲得了讀鎖, 時間為" + System.currentTimeMillis()); }finally{ lock.unlock(); } } public void handleWrite(Lock lock) throws InterruptedException{ try{ lock.lock(); Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " 獲得了寫鎖, 時間為" + System.currentTimeMillis()); }finally{ lock.unlock(); } } @Override public void run() { } public static void main(String[] args) { final ReadWriteLockTest rwlt = new ReadWriteLockTest(); Runnable read = new Runnable(){ public void run(){ try { rwlt.handleRead(readLock); //rwlt.handleRead(rl); //假如使用普通的重入鎖,讀寫之間相互等待 } catch (InterruptedException e) { e.printStackTrace(); } } }; Runnable write = new Runnable(){ public void run(){ try{ rwlt.handleWrite(writeLock); //rwlt.handleWrite(rl); //假如使用普通的重入鎖,讀寫之間相互等待 } catch (InterruptedException e) { e.printStackTrace(); } } }; Thread[] readThread = new Thread[10]; for (int i = 0; i < 10; i++) { readThread[i] = new Thread(read); readThread[i].start(); } Thread[] writeThread = new Thread[5]; for (int i = 0; i < 5; i++) { writeThread[i] = new Thread(write); writeThread[i].start(); } } }

在JDK1.8之前,ReentrantReadWriteLock是ReadWriteLock的唯一實現,它由讀、寫鎖組成,讀是共享鎖、寫是獨占鎖,且讀寫互斥,它使用的依然是悲觀的鎖策略.如果有大量的讀線程,他也有可能引起寫線程的饑餓。JDK1.8,引進一種新的機制(StampedLock),StampedLock則提供了一種樂觀的讀策略,這種樂觀策略的鎖非常類似於無鎖的操作,使得樂觀鎖完全不會阻塞寫線程。

java多線程---讀寫鎖ReadWriteLock