今天學習ReentrantReadWriteLock工具類,該類是JUC原子包中的類,通過單元測試代碼把所有public api方法跑了一遍,大致瞭解了底層實現,初學乍練,有很多一知半解的地方,待後續有了深入理解再來補充
package test.java.util.concurrent.locks;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.junit.Test;
/**
* ReentrantReadWriteLock的測試類
*
* @author zqw
* @date 2020-06-22 22:18:53
*/
public class ReentrantReadWriteLockTest {
/**
* 無參構造函數,默認非公平鎖,效率高
* 同時初始化readLock和writeLock
* void
* @Param
* @author zhqwm
* @date 2020/6/21 23:21
*/
@Test
public void testConstruct0()throws Exception{
ReentrantReadWriteLock testObj=new ReentrantReadWriteLock(true);
System.out.println(testObj.toString());
}
/**
* 有參構造函數,指定公平鎖和非公平鎖
* 公平鎖搶不到的線程入隊等待執行
* 同時初始化readLock和writeLock
* void
* @Param
* @author zhqwm
* @date 2020/6/21 23:21
*/
@Test
public void testConstruct1()throws Exception{
ReentrantReadWriteLock testObj=new ReentrantReadWriteLock(true);
System.out.println(testObj.toString());
}
class TestReadWriteLockThread extends Thread{
ReentrantReadWriteLock lock=null;
public TestReadWriteLockThread(String name,ReentrantReadWriteLock lock){
super(name);
this.lock=lock;
}
@Override
public void run() {
try {
lock.writeLock().lock();
System.out.println("獲得鎖:"+getName());
// Thread.sleep(100); ???? 爲啥不能加睡眠,加上就釋放不了鎖
}catch (Exception e){
}finally {
System.out.println("釋放鎖:"+getName());
lock.writeLock().unlock();
}
}
}
/**
* 寫鎖爲公共靜態內部類,外部可以訪問
* 讀讀共享,讀寫互斥,寫讀互斥,寫寫互斥
* void
* @Param
* @author zhqwm
* @date 2020/6/21 23:21
*/
@Test
public void testWriteLock()throws Exception{
ReentrantReadWriteLock testObj=new ReentrantReadWriteLock(true);
TestReadWriteLockThread test=new TestReadWriteLockThread("lock",testObj);
TestReadWriteLockThread test1=new TestReadWriteLockThread("lock1",testObj);
TestReadWriteLockThread test2=new TestReadWriteLockThread("lock2",testObj);
test.start();
test1.start();
test2.start();
}
class TestReadWriteLockThread1 extends Thread{
ReentrantReadWriteLock lock=null;
public TestReadWriteLockThread1(String name,ReentrantReadWriteLock lock){
super(name);
this.lock=lock;
}
@Override
public void run() {
try {
lock.readLock().lock();
System.out.println("獲得鎖:"+getName());
// Thread.sleep(2000);
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println("釋放鎖:"+getName());
lock.readLock().unlock();
}
}
}
/**
* 讀鎖爲公共靜態內部類,外部可以訪問
* 讀讀共享,讀寫互斥,寫讀互斥,寫寫互斥
*結果: 獲得讀鎖:lock
* 獲得讀鎖:lock1
* 釋放讀鎖:lock1
* 釋放讀鎖:lock
* void
* @Param
* @author zhqwm
* @date 2020/6/21 23:21
*/
@Test
public void testReadLock()throws Exception{
ReentrantReadWriteLock testObj=new ReentrantReadWriteLock(true);
TestReadWriteLockThread1 test=new TestReadWriteLockThread1("lock",testObj);
TestReadWriteLockThread1 test1=new TestReadWriteLockThread1("lock1",testObj);
test.start();
test1.start();
}
/**
* 是否是公平鎖
* void
* @Param
* @author zhqwm
* @date 2020/6/22 0:20
*/
@Test
public void testIsFair()throws Exception{
ReentrantReadWriteLock testObj=new ReentrantReadWriteLock(true);
System.out.println(testObj.isFair());
}
class TestReadWriteLockThread2 extends Thread{
ReentrantReadWriteLock lock=null;
public TestReadWriteLockThread2(String name,ReentrantReadWriteLock lock){
super(name);
this.lock=lock;
}
@Override
public void run() {
try {
lock.readLock().lock();
System.out.println("獲取鎖:"+getName());
System.out.println(getName()+":"+lock.getReadLockCount());
// Thread.sleep(3000);
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println("釋放鎖:"+getName());
lock.readLock().unlock();
}
}
}
/**
* 獲取佔有讀鎖的線程數量
* void
* @Param
* @author zhqwm
* @date 2020/6/22 0:20
*/
@Test
public void testGetReadLockCount()throws Exception{
ReentrantReadWriteLock testObj=new ReentrantReadWriteLock(true);
TestReadWriteLockThread2 test=new TestReadWriteLockThread2("lock",testObj);
TestReadWriteLockThread2 test1=new TestReadWriteLockThread2("lock1",testObj);
test.start();
test1.start();
}
/**
* 寫鎖是否被鎖住
* void
* @Param
* @author zhqwm
* @date 2020/6/22 0:20
*/
@Test
public void testIsWriteLocked()throws Exception{
ReentrantReadWriteLock testObj=new ReentrantReadWriteLock(true);
testObj.writeLock().lock();
System.out.println(testObj.isWriteLocked());
}
/**
* 寫鎖是否被當前線程持有
* void
* @Param
* @author zhqwm
* @date 2020/6/22 0:20
*/
@Test
public void testIsWriteLockedByCurrentThread()throws Exception{
ReentrantReadWriteLock testObj=new ReentrantReadWriteLock(true);
testObj.writeLock().lock();
System.out.println(testObj.isWriteLockedByCurrentThread());
}
/**
* 寫鎖被當前線程重入的次數
* void
* @Param
* @author zhqwm
* @date 2020/6/22 0:20
*/
@Test
public void testGetWriteHoldCount()throws Exception{
ReentrantReadWriteLock testObj=new ReentrantReadWriteLock(true);
testObj.writeLock().lock();
testObj.writeLock().lock();
System.out.println(testObj.getWriteHoldCount());
}
/**
* 讀鎖被當前線程重入的次數
* void
* @Param
* @author zhqwm
* @date 2020/6/22 0:20
*/
@Test
public void testGetReadHoldCount()throws Exception{
ReentrantReadWriteLock testObj=new ReentrantReadWriteLock(true);
testObj.readLock().lock();
testObj.readLock().lock();
System.out.println(testObj.getReadHoldCount());
}
/**
* 等待隊列中是否還有線程
* 即head!=tail
* true 有 false 沒有
* void
* @Param
* @author zhqwm
* @date 2020/6/22 0:20
*/
@Test
public void testHasQueuedThreads()throws Exception{
ReentrantReadWriteLock testObj=new ReentrantReadWriteLock(true);
System.out.println(testObj.hasQueuedThreads());
}
/**
* 參數線程是否在等待隊列中
* void
* @Param
* @author zhqwm
* @date 2020/6/22 0:20
*/
@Test
public void testHasQueuedThread()throws Exception{
ReentrantReadWriteLock testObj=new ReentrantReadWriteLock(true);
TestReadWriteLockThread2 test1=new TestReadWriteLockThread2("lock1",testObj);
test1.start();
Thread.sleep(5000);
System.out.println(testObj.hasQueuedThread(test1));
}
/**
* 獲取等待獲取鎖定的線程數
* void
* @Param
* @author zhqwm
* @date 2020/6/22 0:20
*/
@Test
public void testGetQueueLength()throws Exception{
ReentrantReadWriteLock testObj=new ReentrantReadWriteLock(true);
System.out.println(testObj.getQueueLength());
}
/**
* 是否有等待線程
* 讀鎖不支持,寫鎖支持
* void
* @Param
* @author zhqwm
* @date 2020/6/22 0:20
*/
@Test
public void testHasWaiters()throws Exception{
ReentrantReadWriteLock testObj=new ReentrantReadWriteLock(true);
testObj.writeLock().lock();
System.out.println(testObj.hasWaiters(testObj.writeLock().newCondition()));
}
/**
* w.waitStatus == Node.CONDITION
* 獲取cond.await中的線程數量
* void
* @Param
* @author zhqwm
* @date 2020/6/22 0:20
*/
@Test
public void testGetWaitQueueLength()throws Exception{
ReentrantReadWriteLock testObj=new ReentrantReadWriteLock(true);
testObj.writeLock().lock();
System.out.println(testObj.getWaitQueueLength(testObj.writeLock().newCondition()));
}
/**
* toString
* [Write locks = 0, Read locks = 0]
* void
* @Param
* @author zhqwm
* @date 2020/6/23 1:36
*/
@Test
public void testToString()throws Exception{
ReentrantReadWriteLock testObj=new ReentrantReadWriteLock(true);
System.out.println(testObj.toString());
}
}