高同時実行-ボリューム4-読み書きロック

12787 ワード

ReentrantLockロックの反発性は、同じ時間内にlock()の下で1つのスレッドしか実行できないことを決定します.しかし、読み取りと読み取りの場合、2つのスレッドを反発させる必要はありません.読み書き、書き込みに反発する必要があります.そのため、JDKでは、ReentrantReadWriteLock()という読み書きロックのメカニズムが提案されています.例えば、ユーザーを更新するときに、他のスレッドを読むことはできません.スレッド1が半分に更新される可能性があるからです.スレッド2で読み取ったデータが「ダーティデータ」です.
読み上げる
読み返すことはできない.
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class T{
    public static void main(String[] args) throws InterruptedException {
        final Config config = new Config();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    config.read();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A" ).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    config.read();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }               
            }
        },"B").start();
    }
}

class Config{
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    public void read() throws InterruptedException{
        try{
            lock.readLock().lock();
            System.out.println(Thread.currentThread().getName() + "-" + System.currentTimeMillis());
            Thread.sleep(5000);
        }finally{
            lock.readLock().unlock();
        }
    }
}

出力結果:A-1532191985368 B-1532191985369
  • 出力結果から、読み取りは反発しないことがわかる.

  • 読み書き
    読み書き反発
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    public class T{
        public static void main(String[] args) throws InterruptedException {
            final Config config = new Config();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        config.read();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            },"A" ).start();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        config.write();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }               
                }
            },"B").start();
        }
    }
    
    class Config{
        private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        public void read() throws InterruptedException{
            try{
                lock.readLock().lock();
                System.out.println(Thread.currentThread().getName() + "-" + System.currentTimeMillis());
                Thread.sleep(5000);
            }finally{
                lock.readLock().unlock();
            }
        }
        Thread.sleep(100);
        public void write() throws InterruptedException{
            try{
                lock.writeLock().lock();
                System.out.println(Thread.currentThread().getName() + "-" + System.currentTimeMillis());
                Thread.sleep(5000);
            }finally{
                lock.writeLock().unlock();
            }
        }
    }
    

    出力結果:A-1532192608317 B-1532192613317
  • 出力結果から、読み書き反発が見られる.

  • 書き写す
    書き、反発する.lock.writeLock().lock()
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    public class T{
        public static void main(String[] args) throws InterruptedException {
            final Config config = new Config();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        config.write();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            },"A" ).start();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        config.write();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }               
                }
            },"B").start();
        }
    }
    
    class Config{
        private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        public void read() throws InterruptedException{
            try{
                lock.readLock().lock();
                System.out.println(Thread.currentThread().getName() + "-" + System.currentTimeMillis());
                Thread.sleep(5000);
            }finally{
                lock.readLock().unlock();
            }
        }
    
        public void write() throws InterruptedException{
            try{
                lock.writeLock().lock();
                System.out.println(Thread.currentThread().getName() + "-" + System.currentTimeMillis());
                Thread.sleep(5000);
            }finally{
                lock.writeLock().unlock();
            }
        }
    }
    

    出力結果:A-1532223606586 B-1532223641586
    ライトリード
    ライトリード反発
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    public class T{
        public static void main(String[] args) throws InterruptedException {
            final Config config = new Config();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        config.write();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            },"A" ).start();
            Thread.sleep(100);
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        config.read();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }               
                }
            },"B").start();
        }
    }
    
    class Config{
        private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        public void read() throws InterruptedException{
            try{
                lock.readLock().lock();
                System.out.println(Thread.currentThread().getName() + "-" + System.currentTimeMillis());
                Thread.sleep(5000);
            }finally{
                lock.readLock().unlock();
            }
        }
    
        public void write() throws InterruptedException{
            try{
                lock.writeLock().lock();
                System.out.println(Thread.currentThread().getName() + "-" + System.currentTimeMillis());
                Thread.sleep(5000);
            }finally{
                lock.writeLock().unlock();
            }
        }
    }
    

    出力結果:A-1532223606586 B-1532223641586