ReadWriteLock使用,适用于什么?java

KLQ 2020-08-04 10:58:22 java常见问答 8068

下面的文章内容要给大家介绍的就是ReadWriteLock,一起来了解一下ReadWriteLock的使用方法以及它的适用场景吧。

ReadWriteLock使用方法:

/**
 * 多个线程同时读一个资源类没有任何问题,所以为了满足并发量,读取共享资源
 * 应该同时进行。
 * 但是,如果有一个线程想去写共享资源来,就不应该再有其它线程可以对该资源进行读或者写
 * 小结:
 * 读—读能共存
 * 读写不能共存
 * 写写不能共存
 */
public static void main(String[] args)
{
    Mycache mycache = new Mycache();
    for (int i = 0; i <= 5; i++)
    {
        final int t = i;
        new Thread(() - >
            {
                mycache.put(Thread.currentThread()
                    .getName(), t + "");
            }, String.valueOf(i))
            .start();
    }
    for (int i = 0; i <= 5; i++)
    {
        new Thread(() - >
            {
                mycache.get(Thread.currentThread()
                    .getName());
            }, String.valueOf(i))
            .start();
    }
}
}
class Mycache
{
    private volatile HashMap < String, Object > hashMap = new HashMap < > ();
    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    public void put(String key, Object value)
    {
        readWriteLock.writeLock()
            .lock();
        try
        {
            System.out.println(Thread.currentThread()
                .getName() + "\t写入数据" + key);
            hashMap.put(key, value);
            System.out.println(Thread.currentThread()
                .getName() + "\t写入完成");
        }
        catch (Exception e)
        {}
        finally
        {
            readWriteLock.writeLock()
                .unlock();
        }
    }
    public void get(String key)
    {
        readWriteLock.readLock()
            .lock();
        try
        {
            System.out.println(Thread.currentThread()
                .getName() + "\t读取数据" + key);
            hashMap.get(key);
            System.out.println(Thread.currentThread()
                .getName() + "\t读取完成");
        }
        catch (Exception e)
        {}
        finally
        {
            readWriteLock.readLock()
                .unlock();
        }
    }

ReadWriteLock使用案例

举个例子来应用读写锁,ReentrantReadWriteLock是ReadWriteLock的实现类。

最主要的有2个方法:readLock()和writeLock()用来获取读锁和写锁。

代码:

public class ReadWriteLockDemo
{
    private static final ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
    private static ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
    private static ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
    public static void main(String[] args)
    {
        new Thread(() - > read())
            .start();
        new Thread(() - > read())
            .start();
        new Thread(() - > write())
            .start();
        new Thread(() - > write())
            .start();
    }
    private static void read()
    {
        String threadName = Thread.currentThread()
            .getName();
        readLock.lock();
        try
        {
            System.out.println(threadName + "-获取读锁(readLock),读取数据...");
            Thread.sleep(1000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        finally
        {
            System.out.println(threadName + "-释放读锁(readLock)");
            readLock.unlock();
        }
    }
    private static void write()
    {
        String threadName = Thread.currentThread()
            .getName();
        writeLock.lock();
        try
        {
            System.out.println(threadName + "-获取写锁(writeLock),写入数据...");
            Thread.sleep(1000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        finally
        {
            System.out.println(threadName + "-释放读锁(writeLock)");
            writeLock.unlock();
        }
    }
}

结果:

Thread - 0 - 获取读锁(readLock), 读取数据...
Thread - 1 - 获取读锁(readLock), 读取数据...
Thread - 0 - 释放读锁(readLock)
Thread - 1 - 释放读锁(readLock)
Thread - 2 - 获取写锁(writeLock), 写入数据...
Thread - 2 - 释放写锁(writeLock)
Thread - 3 - 获取写锁(writeLock), 写入数据...
Thread - 3 - 释放写锁(writeLock)

1、线程0和线程1都获得了读锁,读取数据;

2、可是线程2获得写锁之后,线程3在线程2释放了写锁之后,才获取写锁,写入数据。

读写锁适用场合

和ReentrantLock适用于一般场合相比,ReadWriteLock适用于读多写少的情况,合理使用可以进一步提高并发效率。

对于ReadWriteLock的介绍就到这里啦,更多java项目中常见问题请继续关注奇Q工具网来进行了解吧。

推荐阅读:

ReentrantLock属于乐观锁还是悲观锁?

ReentrantLock的实现原理是怎样的?详解

sychronized和reentrantlock区别在哪里?都有什么用处?