1. 程式人生 > >執行緒讀寫鎖

執行緒讀寫鎖

先看案例,如下

package hello_java;

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

public class ReadAndWrite {
    public static void main(String[] args) {
        ShareData04 shareData04 = new ShareData04();
        new Thread(() -> {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            shareData04.write("juc....");
        }).start();

        for (int i = 0; i < 20; i++) {
            new Thread(() -> {
                shareData04.read();
            }).start();
        }

    }
}

class ShareData04 {
    private String content;
    Lock lock = new ReentrantLock();

    public String read() {
        lock.lock();
        try {
            System.out.println("Student" + Thread.currentThread().getName() + "get = " + content);
            return content;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return "";
    }

    public void write(String content) {
        lock.lock();
        try {
            this.content = content;
            System.out.println("The teacher write the content : " + content);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}


執行的結果,如下:

StudentThread-1get = null
StudentThread-4get = null
The teacher write the content : juc....
StudentThread-3get = juc....
StudentThread-2get = juc....
StudentThread-5get = juc....
StudentThread-7get = juc....

出現了,有的學生可以讀到了資料,有的學生讀不到資料的情況。正常的情況應該是,一旦老師修改了資料,所有的學生都應該可以看到資料。為什麼會出現這樣的現象呢?老師的執行緒先被啟動,但是休眠了兩毫秒,在這兩毫秒,學生執行緒有若干被建立,並開始執行,兩毫秒到了,老師插進來了,軟體是不能這樣設計的。

讀的時候,不能寫 即讀寫分離,寫的時候;讀和讀可以併發,寫和寫也是互斥的。

 解決該問題的方案如下:

 

package hello_java;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadAndWrite {
    public static void main(String[] args) {
        ShareData04 shareData04 = new ShareData04();
        new Thread(() -> {
            shareData04.write("juc....");
        }).start();

        for (int i = 0; i < 20; i++) {
            new Thread(() -> {
                shareData04.read();
            }).start();
        }

    }
}

class ShareData04 {
    private String content;
    private ReadWriteLock lock = new ReentrantReadWriteLock();
    public String read() {
        lock.readLock().lock();
        try {
            System.out.println("Student" + Thread.currentThread().getName() + "get = " + content);
            return content;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.readLock().unlock();
        }
        return "";
    }

    public void write(String content) {
        lock.writeLock().lock();
        try {
            this.content = content;
            System.out.println("The teacher write the content : " + content);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.writeLock().unlock();
        }
    }
}


執行結果如下:

The teacher write the content : juc....
StudentThread-1get = juc....
StudentThread-2get = juc....
StudentThread-4get = juc....
StudentThread-3get = juc....