JUC

ReadWriteLock


基本讲解与使用

① ReadWriteLock同Lock一样也是一个接口,提供了readLock和writeLock两种锁的操作机制,一个是只读的锁,一个是写锁。

读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的(排他的)。 每次只能有一个写线程,但是可以有多个线程并发地读数据。

所有读写锁的实现必须确保写操作对读操作的内存影响。换句话说,一个获得了读锁的线程必须能看到前一个释放的写锁所更新的内容。

理论上,读写锁比互斥锁允许对于共享数据更大程度的并发。与互斥锁相比,读写锁是否能够提高性能取决于读写数据的频率、读取和写入操作的持续时间、以及读线程和写线程之间的竞争。

② 使用场景

假设你的程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁。

例如,最初填充有数据,然后很少修改的集合,同时频繁搜索(例如某种目录)是使用读写锁的理想候选项。

在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源。但是如果有一个线程想去写这些共享资源,就不应该再有其它线程对该资源进行读或写。这就需要一个读/写锁来解决这个问题。

③ 互斥原则:

读-读能共存,
读-写不能共存,
写-写不能共存。

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

public class ReadWriteLockDemo {
    private ReadWriteLock readWriteLock= new ReentrantReadWriteLock();
    private int number=0;

    public void get(){
        readWriteLock.readLock().lock();
        try{
            System.out.println(Thread.currentThread().getName()+"线程读取中。。");
            System.out.println("number:"+number);
        }finally {
            readWriteLock.readLock().unlock();
        }
    }

    public void set(Integer num){
        readWriteLock.writeLock().lock();
        try{
            System.out.println(Thread.currentThread().getName()+"线程写入中...........................................");
            Thread.sleep(1000);
            this.number=num;
            System.out.println("number:"+number);
            System.out.println("写入成功!");
            System.out.println();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        //创建30个读线程,10个写线程
        ReadWriteLockDemo readWriteLockDemo=new ReadWriteLockDemo();
        for (int i = 0; i < 30; i++) {
            final int L=i;
            new Thread(()->{
                readWriteLockDemo.get();
            },L+"线程").start();
        }

        for (int i = 40; i < 50; i++) {
            final int L=i;
            new Thread(()->{
                readWriteLockDemo.set(L);
            },L+"线程").start();
        }


    }

}

0线程线程读取中。。
number:0
1线程线程读取中。。
number:0
2线程线程读取中。。
number:0
4线程线程读取中。。
number:0
3线程线程读取中。。
number:0
6线程线程读取中。。
number:0
5线程线程读取中。。
7线程线程读取中。。
number:0
8线程线程读取中。。
number:0
10线程线程读取中。。
number:0
number:0
9线程线程读取中。。
number:0
11线程线程读取中。。
number:0
12线程线程读取中。。
number:0
13线程线程读取中。。
number:0
16线程线程读取中。。
number:0
15线程线程读取中。。
number:0
14线程线程读取中。。
number:0
17线程线程读取中。。
number:0
19线程线程读取中。。
number:0
18线程线程读取中。。
number:0
22线程线程读取中。。
number:0
20线程线程读取中。。
number:0
24线程线程读取中。。
number:0
26线程线程读取中。。
number:0
28线程线程读取中。。
number:0
40线程线程写入中...........................................
number:40
写入成功!

21线程线程读取中。。
number:40
42线程线程写入中...........................................
number:42
写入成功!

44线程线程写入中...........................................
number:44
写入成功!

29线程线程读取中。。
number:44
46线程线程写入中...........................................
number:46
写入成功!

43线程线程写入中...........................................
number:43
写入成功!

25线程线程读取中。。
23线程线程读取中。。
number:43
number:43
47线程线程写入中...........................................
number:47
写入成功!

27线程线程读取中。。
number:47
49线程线程写入中...........................................
number:49
写入成功!

45线程线程写入中...........................................
number:45
写入成功!

41线程线程写入中...........................................
number:41
写入成功!

48线程线程写入中...........................................
number:48
写入成功!


  • 作者:低调做个路人 (扫码联系作者)
  • 发表时间:2019-12-12 02:12:01
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 评论

    321
    321
    123
    123456
    a   @123
    123 hi