这段代码,我开始的想法是t1是读锁,t2是写锁,t3是读锁
那么t1,上锁了后,t2的写锁是上不了的,t3的读锁是可以上的
那么假如顺序是t1,t2,t3的启动顺序,那么读出count的值:t1:0,t3:0,t2:5
但是实际情况却不是,为什么呢?
这个就是ReentrantReadWriteLock的精妙所在了
写锁加不上后,那么后面的读锁肯定也加不上了
这是因为在写后面的读,必须要在写之后,否则就会读脏数据
所以我猜测,在获取读锁之前肯定要判断一下是否有写锁被阻塞,如果有写锁被阻塞,那么就不可以读
class Data{
private Integer count;
private ReentrantReadWriteLock reentrantReadWriteLock;
Data(){
this.count=0;
this.reentrantReadWriteLock=new ReentrantReadWriteLock();
}
public void setCount(int count) {
System.out.println(Thread.currentThread().getName()+"要加写锁了");
reentrantReadWriteLock.writeLock().lock();
System.out.println(Thread.currentThread().getName()+"获取了此资源,正在写数据");
try{
Thread.sleep(3000);
this.count = count;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName()+"修改了了count的值,为:"+count);
reentrantReadWriteLock.writeLock().unlock();
}
}
public Integer getCount() {
System.out.println(Thread.currentThread().getName()+"要加读锁了");
reentrantReadWriteLock.readLock().lock();
System.out.println(Thread.currentThread().getName()+"获取了此资源,正在读数据");
try{
Thread.sleep(3000);
return count;
} catch (InterruptedException e) {
e.printStackTrace();
return null;
}finally {
System.out.println(Thread.currentThread().getName()+"获取了count的值,为:"+count);
reentrantReadWriteLock.readLock().unlock();
}
}
}
public class ReentrantReadWriteLockTest {
private static Data data=new Data();
private static CountDownLatch countDownLatch=new CountDownLatch(3);
public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
Integer count=data.getCount();
countDownLatch.countDown();
}
},"t1").start();
new Thread(new Runnable() {
public void run() {
int count=5;
data.setCount(count);
countDownLatch.countDown();
}
},"t2").start();
new Thread(new Runnable() {
public void run() {
Integer count=data.getCount();
countDownLatch.countDown();
}
},"t3").start();
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
public void run() {
Integer count=data.getCount();
}
},"t4").start();
}
}