Java~理解認識 讀寫鎖

理解認識讀寫鎖

  • 所謂讀寫鎖,即是讀鎖和寫鎖的統稱,它是兩種鎖,但放在同一個對象裏
  • 它把對共享資源的訪問者劃分成讀者和寫者,讀者只對共享資源進行讀訪問,寫者則需要對共享資源進行寫操作
  • 在多處理器系統中,它允許同時有多個讀者來訪問共享資源,最大可能的讀者數爲實際的邏輯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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章