Administrator
Published on 2021-06-30 / 256 Visits
0

【线程与并发】ReentrantLock与ReadWriteLock

ReentrantLock与ReadWriteLock

ReentrantLock

互斥锁,lock将语句块标记为临界区,当一个线程获取到锁后,其他线程如果需要使用该临界区则必须要等待前一个线程使用完毕后释放锁后才可以使用。

ReadWriteLock

读写锁,可以提高并发访问的性能,使用readwritelock 锁的话,当拥有该对象的某个线程在进行读取时,其他线程也可以进行读取,但是不能写入操作;当该线程进行写入操作时,其他线程不可以读取和写入。

补充

此外还有ReadWriteLock的改进的一个锁:StampedLock

样例

import java.text.SimpleDateFormat;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Test {
    private static int value;

    //互斥锁
    static Lock lock = new ReentrantLock();
    //读写锁
    static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    static Lock readLock = readWriteLock.readLock();
    static Lock writeLock = readWriteLock.writeLock();

    public static void read(Lock lock){
        try {
            lock.lock();
            TimeUnit.SECONDS.sleep(1);
            System.out.println(getTime() + "读执行完毕");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void write(Lock lock , int value){
        try {
            lock.lock();
            TimeUnit.SECONDS.sleep(1);
            Test.value = value;
            System.out.println(getTime() + "写执行完毕");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        //1互斥锁,读的线程在不在同一时间执行完毕
        Runnable readR = () -> read(lock);
        Runnable writeR = () -> write(lock,new Random().nextInt());

        //2读写锁,读的线程在同一时间执行完毕
//        Runnable readR = () -> read(readLock);
//        Runnable writeR = () -> write(writeLock,new Random().nextInt());

        for (int i = 0; i < 5; i++) new Thread(readR).start();
        for (int i = 0; i < 2; i++) new Thread(writeR).start();
    }

    public static String getTime(){
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return df.format(System.currentTimeMillis());
    }

    /* 互斥锁的执行结果:
    2021-06-27 21:31:25读执行完毕
    2021-06-27 21:31:26读执行完毕
    2021-06-27 21:31:27读执行完毕
    2021-06-27 21:31:28读执行完毕
    2021-06-27 21:31:29读执行完毕
    2021-06-27 21:31:30写执行完毕
    2021-06-27 21:31:31写执行完毕
     */

    /* 读写锁的执行结果:
    2021-06-27 21:32:15读执行完毕
    2021-06-27 21:32:15读执行完毕
    2021-06-27 21:32:15读执行完毕
    2021-06-27 21:32:15读执行完毕
    2021-06-27 21:32:15读执行完毕
    2021-06-27 21:32:16写执行完毕
    2021-06-27 21:32:17写执行完毕
     */

}