Java多线程之Lock接口
锁Lock接口
定义:Lock接口的功能跟synchronzied一样的,只不过synchronized同步块执行结束后锁会自动释放,而lock接口必须要调用unlock()方法释放锁。Lock接口的其他方面会比synchronized更为灵活,提供了一些方法和多方式控制加锁 / 解锁,可以选择线程进行一些操作。
锁Lock接口区分:
1、公平锁:意思是线程获取锁的顺序是按先来先得顺序的,就是线程加锁的顺序来分配的。
2、非公平锁:就是随机性获得锁,没有顺序的
写法上区分:
Lock lock = ReentrantLock(true) / ReentrantLock();
ReentrantReadWriteLock lock = new ReentrantReadWriteLock() ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); 是为公平锁;
Lock lock = ReentrantLock(false)
ReentrantReadWriteLock lock = new ReentrantReadWriteLock(false) 是为非公平锁;
Lock接口有几个方法:

提供多种加锁方案,lock 阻塞式, trylock 无阻塞式, lockInterruptily 可打断式, 还有trylock的带超时时间版本。
还有一些常用的方法,自行搜索。
Lock接口的实现类 主要三个:ReentrantLock , ReentrantReadWriteLock.ReadLock , ReentrantReadWriteLock.WriteLock 。
因为Lock是接口所以使用时要结合它的实现类,
另外在finall语句块中释放锁的目的是保证获取到锁之后,最终能够被释放。
1、ReentrantLock实现类:
需要上锁的对象

多线程实现

调用多线程

返回的结果:

从结果上看: 确实是一条线程执行完之后 再到另一条执行的。
2、ReentrantReadWriteLock实现类
ReentrantReadWriteLock 望文生义就是可重复进入读写锁,读取锁 和 写入锁 ,
读取锁含义:在同一时刻可以被多个读线程访问,线程之间不存在阻塞;
写入锁含义: 在多个写入线程同一时刻进行访问写入时,只有一个线程可以写入,其他写入线程和所有读取线程都会被阻塞。
所以,可以肯定的是 读取锁之间并不互相排斥,而写入锁之间和与之读取锁是互相排斥的。
简单的调用就是这样:

Lock接口源码内部是通过getState()获取的是读锁与写锁总同步状态,再通过exclusiveCount()方法单独获取写锁同步状态;
在获取写入锁时,当多线线程存在读锁获取写锁时,则会获取写锁失败;否则获取成功,增加写锁同步状态。
在获取读取锁时, 首先写入锁状态为0 时才能开始获取读取锁,读取锁类似共享锁多线程此时都可以访问读写锁,然后读取锁状态会加一进行计数。
总得来说,读写锁适合于并发编程中程序读取数据操作次数多而大,写入数据操作少的场景
网友评论