Java8新的读写锁StampedLock

StampedLock类是一个读写锁的改进,它的思想是读写锁中读不仅不阻塞读,同时也不应该阻塞写。在读的时候如果发生了写,则应当重读而不是在读的时候直接阻塞写!因为在读线程非常多而写线程比较少的情况下,写线程可能发生饥饿现象,也就是因为大量的读线程存在并且读线程都阻塞写线程,因此写线程可能几乎很少被调度成功!当读执行的时候另一个线程执行了写,则读线程发现数据不一致则执行重读即可。所以读写都存在的情况下,使用StampedLock就可以实现一种无障碍操作,即读写之间不会阻塞对方,但是写和写之间还是阻塞的!

/**
 * Java8 新的读写锁的使用
 *
 * <p>新的读写锁的实现思路是在读远大于写的应用场景中读不会直接影响写,导致写操作的饥饿<p/><br/>
 * <p>读的时候可以尝试获取锁,获取不到不会直接上锁,可以循环尝试,也可以尝试一定次数后上悲观读锁</p>
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2018/11/7 10:24
 * @since jdk1.8
 */
public class StampedLockTests {
    private int shareObj = 0;
    private StampedLock lock = new StampedLock();

    private void add() {
        //添加写锁
        long stamp = lock.writeLock();
        try {
            shareObj++;
        }finally {
            lock.unlock(stamp);
        }
    }

    public void get() {

        //校验获取的锁是否成功
        boolean flag = false;
        //尝试获取五次锁
        for (int i = 0; i < 5 ; i++) {
            //尝试获取读锁
            long stamp = lock.tryOptimisticRead();
            if (lock.validate(stamp)) {
                flag = true;
                break;
            }else {
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        if (!flag) {
            //五次都没获取到,只好加一个悲观读锁了
            long stamp = lock.readLock();
            try {
                System.out.println(shareObj);
            } finally {
                lock.unlockRead(stamp);
            }
        } else {
            System.out.println(shareObj);
        }
    }

    @Test
    public void test1() {
        Runnable runnable1 = () -> {
            add();
        };
        Runnable runnable2 = () -> {
            get();
        };
        new Thread(runnable1).start();
        new Thread(runnable2).start();
        new Thread(runnable1).start();
        new Thread(runnable2).start();
        new Thread(runnable2).start();
        new Thread(runnable1).start();
        new Thread(runnable2).start();
        new Thread(runnable2).start();
        new Thread(runnable2).start();
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值