ReentrantReadWriteLock示例

public class ReentrantReadWriteLockTest {
    
    private Map<String, String> map = new HashMap<>();
    
    public static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    
    //获取读锁
    private Lock readLock = readWriteLock.readLock();

    //获取写锁
    private Lock writeLock = readWriteLock.writeLock();
    
    public static void main(String[] args) throws InterruptedException {
        //testReenter();
        //testUpgrade();
        //testDowngrade();
        
        ReentrantReadWriteLockTest reentrantReadWriteLockTest = new ReentrantReadWriteLockTest();
          //写操作测试  可以知道写操作是互斥的
        Runnable runnable1 = () -> {
            for (int i = 0; i < 5; i++) {
                reentrantReadWriteLockTest.write("key" + i, "value"+i);
            }

        };
       Thread t1 =  new Thread(runnable1);
       Thread t2 =  new Thread(runnable1);
       Thread t3 =  new Thread(runnable1);
       t1.start();
       t2.start();
       t3.start();
       t1.join();
       t2.join();
       t3.join();
       System.out.println("开始并发读取。。。");
        
        //读操作测试  可以知道读操作是可以并发执行的
        Runnable runnable2 = () -> {
            for (int i = 0; i < 5; i++) {
                System.out.println(reentrantReadWriteLockTest.read("key" + i));
            }

        };
        new Thread(runnable2).start();
        new Thread(runnable2).start();
        new Thread(runnable2).start();
    }
    
   /**
           *  在同一个线程中,在没有释放写锁的情况下,就去申请读锁,这属于锁降级,ReentrantReadWriteLock是支持的,不过锁的释放有问题,获取到锁就要释放锁
          *  为什么有锁的降级,在一个线程进行写操作后,  当前线程可以继续读取数据,又不希望别的线程对数据更改,又可以让别的线程可以读取数据
   */
    public static void testDowngrade() {
        ReentrantReadWriteLock rtLock = new ReentrantReadWriteLock();  
        rtLock.writeLock().lock();  
        System.out.println("writeLock");  
        rtLock.readLock().lock();  
        System.out.println("get read lock");  
    }
    
    //在同一个线程中,在没有释放读锁的情况下,就去申请写锁,这属于锁升级,ReentrantReadWriteLock是不支持的。
    public static void testUpgrade() {
          ReentrantReadWriteLock rtLock = new ReentrantReadWriteLock();
          rtLock.readLock().lock();
          System.out.println("get readLock.");
         // rtLock.readLock().unlock();
          rtLock.writeLock().lock();
          System.out.println("blocking");
          rtLock.writeLock().unlock();
    }
    
    //可重入锁,就是说一个线程在获取某个锁后,还可以继续获取该锁,即允许一个线程多次获取同一个锁,要注意的是获取多少次锁就要释放多少次锁,不然会发生死锁,例子讲的是两次获取写锁
    public static void  testReenter() throws InterruptedException {
        final ReentrantReadWriteLock  lock = new ReentrantReadWriteLock ();
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                lock.writeLock().lock();
                System.out.println("Thread real execute");
                lock.writeLock().unlock();
            }
        });

        lock.writeLock().lock();
        lock.writeLock().lock();
        t.start();
        Thread.sleep(200);
        System.out.println("realse one once");
        lock.writeLock().unlock();
      // lock.writeLock().unlock();
    }
    
    
    /**
              * 写操作
     * @param key
     * @param value
     */
    public void write(String key, String value) {
        writeLock.lock();
        System.out.println(Thread.currentThread().getName() + " 写操作正在执行。。。");
        try {
            Thread.sleep(2000);
            map.put(key, value);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            writeLock.unlock();
        }
    }

    
    /**
               * 读操作
     * @param key
     * @return
     */
    public String read(String key) {
        readLock.lock();
        System.out.println(Thread.currentThread().getName() + " 读操作正在执行。。。");
        try {
            Thread.sleep(2000);
            return map.get(key);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readLock.unlock();
        }
        return null;
    }
}

猜你喜欢

转载自www.cnblogs.com/moris5013/p/11764153.html