线程lock-3 ReentrantReadWriteLock

96
传说中的大哥
2018.11.22 17:06* 字数 219

ReentrantReadWriteLock提供了两个锁,一个是读操作的锁,一个是写操作的锁。这两个锁的排斥性:

读-读:不排斥
读-写:互斥
写-写:互斥

声明方式:

ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

例1:有两个线程对同一个文件进行并发读取,(读读操作):

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();
    }
}

运行结果:两个线程的时间相同,说明并发读文件是并行的。不排斥

2018-11-22 16:43:53.053
2018-11-22 16:43:53.053

例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();
    }
}

运行结果:两个线程的时间不同,说明互斥。

读取文件: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:有两个线程对同一个文件进行同时进行写入操作(写写操作)

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();

    }
}

运行结果:两个线程的时间不同,说明互斥。

写入文件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
java线程
Web note ad 1