接上一篇章,对于推测我加入了一个信号量,来进行验证:
相关的代码如下:(修改地方标记为红色)
package ReenTrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriteLockTest {
static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
publicstatic volatile booleantype = true;
public staticvoid main(String[] args) {
// TODO Auto-generated method stub
Mythread t1 = new Mythread("t1");
Mythread t2 = new Mythread("t2");
Mythread t3 = new Mythread("t3");
t1.start();
t2.start();
t3.start();
}
private staticclass Mythread extends Thread{
public Mythread(StringthreadName){
super(threadName);
}
public void run(){
while(true){
while(type){
ReentrantReadWriteLock.ReadLock readlock = null;
try{
readlock =lock.readLock();
readlock.lock();
System.err.println("to read...." +Thread.currentThread().getName());
try {
Thread.sleep(5000);
}catch (InterruptedException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}finally{
readlock.unlock();
type=false;
}
}
while(!type){
ReentrantReadWriteLock.WriteLockwritelock = null;
try{
writelock=lock.writeLock();
writelock.lock();
System.err.println("to write....." +Thread.currentThread().getName());
try {
Thread.sleep(5000);
}catch (InterruptedException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}finally{
writelock.unlock();
type=true;
//System.out.println("----->"+type);
}
}
}
}
}
}
打印的结果:
to read....t2
to read....t3
to read....t1
to write.....t2
to write.....t1
to write.....t3
to read....t3
to read....t2
to read....t1
to write.....t2
to write.....t3
to write.....t1
...符合我coding的预期,所以在此做个大胆的结论:前面写锁unlock的时候,释放的lock被写的线程又直接拿到,就一直打印出写的线程的sysout信息,通过加个信号量,从而使得本身不可控的线程调度被自身设计者掌握。
做的一些小扩展:
1、如果说本身对于读写可以无序的多线程应用场景,则可以直接利用concurrent下面的方法,创建出多个线程,直接start(),无序执行对应的读写run()实体即可
2、对于本身期望可以做到有序控制的多线程场景,则可以利用(或者别的方法,例如利用db本身的数据库锁,还有其它的请客官不吝赐教,留下蛛丝马迹)信号量的方式使得本身的执行过程可控~
Question:
弄明白这些,对做好产品质量,做好测试的帮助是什么?
answer:
在做前期scrum or 程序设计,预评审,代码提交走读阶段就可以提出一些在性能上的注意点(例如程序开发涉及到多线程场景,使用到了concurrent下的locks子包的reentrantreadwritelock,该场景需要有序执行,但无数据库锁设定也无信号量控制,则可能出现执行顺序在>1次的情况下,出现异常。又或者说加了信号量,但本身该信号量的类型和定义方式不正确,也会有问题,比如,上面的代码,如果将type作为int类型,代码做下修改,读的线程执行就+1,下面写的while条件修改为了while(type==2)[type初始值为1,你觉得会如何?会不会出现预期的,read线程执行unlock只有,type+1=2,从而顺利的被写线程执行,写线程unlock之后,type-1=1,从而也顺利的被读线程拿到锁执行呢?)
装个逼,,,自己试一试。。。
谢谢在此过程中给予帮助和指导的jorgen~~~