スレッドlock-3 ReentrantReadWriteLock

4242 ワード

ReentrantReadWriteLockは、読み取り操作のロックと書き込み操作のロックの2つのロックを提供します。この2つのロックの反発性:


読み取り-読み取り:読み取り-書き込みを排斥しない:反発書き-書き込み:反発しない

宣言方法:

ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

例1:同じファイルを2つのスレッドで同時読み取り、(読み取り操作):
import java.text.SimpleDateFormat;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Demo6 {
    /**
     *  
     */
    public static void  readAndWriteFile(){
        try {
            TimeUnit.SECONDS.sleep(2);// 2   
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.sss");
        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        new Thread(()->{
            lock.readLock().lock();// 
            readAndWriteFile();
            lock.readLock().unlock();
            System.out.println(date.format(System.currentTimeMillis()));
        }).start();
        new Thread(()->{
            lock.readLock().lock();// 
            readAndWriteFile();
            lock.readLock().unlock();
            System.out.println(date.format(System.currentTimeMillis()));
        }).start();
    }
}

実行結果:2つのスレッドの時間は同じで、同時読み取りファイルが並列であることを示します.排斥しない
2018-11-22 16:43:53.053
2018-11-22 16:43:53.053

例2:2つのスレッドが同じファイルに対して操作を行い、スレッドがファイルを読み取ると、スレッドがファイルに書き込まれる(読み書き操作):
import java.text.SimpleDateFormat;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Demo6 {
    /**
     *  
     */
    public static void  readAndWriteFile(){
        try {
            TimeUnit.SECONDS.sleep(2);// 2   
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.sss");
        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        // 
        new Thread(()->{
            lock.readLock().lock();
            readAndWriteFile();
            lock.readLock().unlock();
            System.out.println(" :"+date.format(System.currentTimeMillis()));
        }).start();
        // 
        new Thread(()->{
            lock.writeLock().lock();
            readAndWriteFile();
            lock.writeLock().unlock();
            System.out.println(" :"+date.format(System.currentTimeMillis()));
        }).start();
    }
}

実行結果:2つのスレッドの時間が異なり、反発を示します.
 :2018-11-22 16:59:36.036
Disconnected from the target VM, address: '127.0.0.1:63452', transport: 'socket'
 2018-11-22 16:59:38.038

例3:2つのスレッドが同一ファイルに対して同時に書き込みを行う(書き込み操作)
import java.text.SimpleDateFormat;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Demo6 {
    /**
     *  
     */
    public static void  readAndWriteFile(){
        try {
            TimeUnit.SECONDS.sleep(2);// 2   
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.sss");
        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        // 
        new Thread(()->{
            lock.writeLock().lock();
            readAndWriteFile();
            lock.writeLock().unlock();
            System.out.println(" 1:"+date.format(System.currentTimeMillis()));
        }).start();
        // 
        new Thread(()->{
            lock.writeLock().lock();
            readAndWriteFile();
            lock.writeLock().unlock();
            System.out.println(" 2:"+date.format(System.currentTimeMillis()));
        }).start();

    }
}

実行結果:2つのスレッドの時間が異なり、反発を示します.
 1:2018-11-22 17:05:35.035
Disconnected from the target VM, address: '127.0.0.1:63606', transport: 'socket'
 2:2018-11-22 17:05:37.037