理解認識讀寫鎖
- 所謂讀寫鎖,即是讀鎖和寫鎖的統稱,它是兩種鎖,但放在同一個對象裏
- 它把對共享資源的訪問者劃分成讀者和寫者,讀者只對共享資源進行讀訪問,寫者則需要對共享資源進行寫操作
- 在多處理器系統中,它允許同時有多個讀者來訪問共享資源,最大可能的讀者數爲實際的邏輯CPU數。寫者是排他性的,一個讀寫鎖同時只能有一個寫者或多個讀者(與CPU數相關),但不能同時既有讀者又有寫者
- 如果讀寫鎖當前沒有讀者,也沒有寫者,那麼寫者可以立刻獲得讀寫鎖,否則它必須自旋在那裏,直到沒有任何寫者或讀者。
- 如果讀寫鎖沒有寫者,那麼多個讀者都可以可以立即獲得該讀寫鎖,否則讀者必須自旋在那裏,直到寫者釋放該讀寫鎖
- 總而言之
讀鎖是共享的
寫鎖是排他的
讀-讀能共存
讀-寫不能共存
寫-寫不能共存
實現
public class ReadWriteLock {
//創建讀鎖和寫鎖
private static final Object readWaitLock = new Object();
//讀寫線程的個數
private volatile int readCount = 0;
private volatile int writeCount = 0;
//操作的數據
public StringBuilder builder = new StringBuilder();
//讀操作
public void read() throws InterruptedException {
//讀可以有多個但是不能和寫操作共存
//此處用while更好更安全 不然判斷語句就只判斷一次
while (writeCount != 0) {
//此時有寫操作 所以進入等待
synchronized (readWaitLock) {
readWaitLock.wait();
}
}
//進行讀操作 並將讀操作計數器++
readCount++;
System.out.println("進程讀操作:" + builder.toString());
//讀操作執行完畢
readCount--;
synchronized (readWaitLock) {
readWaitLock.notify();
}
}
//寫操作
public void write() throws InterruptedException {
//寫操作只能有一個 而且不能和讀共存
synchronized (readWaitLock) {
//這裏還是使用while循環
while (writeCount != 0 && readCount != 0) {
//只要有讀操作和寫操作存在就等待
readWaitLock.wait();
}
//進行寫操作 並將讀操作計數器++
writeCount++;
System.out.println("寫操作");
builder.append("aaa");
System.out.println("寫執行完畢:" + builder.toString());
//寫操作執行完畢
writeCount--;
}
synchronized (readWaitLock) {
readWaitLock.notify();
}
}
public static void main(String[] args) throws InterruptedException {
//創建多個讀操作和寫操作的線程
ReadWriteLock readWriteLock = new ReadWriteLock();
for (int i = 0; i < 10; i++) {
//十個讀線程
Thread t = new Thread() {
@Override
public void run() {
try {
readWriteLock.read();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
//十個寫線程
Thread t1 = new Thread() {
@Override
public void run() {
try {
readWriteLock.write();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t1.start();
t.start();
}
//主線程休息會
Thread.sleep(2000);
}
}
- 上面代碼是個人實現 如果有錯誤請批評指正
寫操作
寫執行完畢:aaa
寫操作
寫執行完畢:aaaaaa
進程讀操作:aaaaaa
寫操作
寫執行完畢:aaaaaaaaa
進程讀操作:aaaaaaaaa
進程讀操作:aaaaaaaaa
寫操作
寫執行完畢:aaaaaaaaaaaa
進程讀操作:aaaaaaaaaaaa
寫操作
寫執行完畢:aaaaaaaaaaaaaaa
寫操作
寫執行完畢:aaaaaaaaaaaaaaaaaa
寫操作
寫執行完畢:aaaaaaaaaaaaaaaaaaaaa
進程讀操作:aaaaaaaaaaaaaaaaaaaaa
進程讀操作:aaaaaaaaaaaaaaaaaaaaa
寫操作
寫執行完畢:aaaaaaaaaaaaaaaaaaaaaaaa
寫操作
寫執行完畢:aaaaaaaaaaaaaaaaaaaaaaaaaaa
進程讀操作:aaaaaaaaaaaaaaaaaaaaaaaaaaa
進程讀操作:aaaaaaaaaaaaaaaaaaaaaaaaaaa
寫操作
寫執行完畢:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
進程讀操作:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
進程讀操作:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Process finished with exit code 0