首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

(转)深入研究ReentrantLock(重入锁)之引入话题篇

2012-08-31 
(转)深入研究ReentrantLock(重入锁)之引出话题篇一直以来都想好好研究下ReentrantLock,她的独到魅力令我屡

(转)深入研究ReentrantLock(重入锁)之引出话题篇

一直以来都想好好研究下ReentrantLock,她的独到魅力令我屡试不爽,无奈网上实在是没有太多的资料可以参考,于是自己开始深入研究它的内部实现机制,经过数天的研究,终于有点心得体会升华了,记录之……

synchronized原语和ReentrantLock在一般情况下没有什么区别,但是在非常复杂的同步应用中,请考虑使用ReentrantLock,特别是遇到下面2种需求的时候。
1.某个线程在等待一个锁的控制权的这段时间需要中断
2.需要分开处理一些wait-notify,ReentrantLock里面的Condition应用,能够控制notify哪个线程
3.具有公平锁功能,每个到来的线程都将排队等候
下面细细道来……

先说第一种情况,ReentrantLock的lock机制有2种,忽略中断锁和响应中断锁,这给我们带来了很大的灵活性。比如:如果A、B2个线程去竞争锁,A线程得到了锁,B线程等待,但是A线程这个时候实在有太多事情要处理,就是一直不返回,B线程可能就会等不及了,想中断自己,不再等待这个锁了,转而处理其他事情。这个时候ReentrantLock就提供了2种机制,第一,B线程中断自己(或者别的线程中断它),但是ReentrantLock不去响应,继续让B线程等待,你再怎么中断,我全当耳边风(synchronized原语就是如此);第二,B线程中断自己(或者别的线程中断它),ReentrantLock处理了这个中断,并且不再等待这个锁的到来,完全放弃。(如果你没有了解java的中断机制,请参考下相关资料,再回头看这篇文章,80%的人根本没有真正理解什么是java的中断,呵呵)

这里来做个试验,首先搞一个Buffer类,它有读操作和写操作,为了不读到脏数据,写和读都需要加锁,我们先用synchronized原语来加锁,如下:

            public?class?Reader?extends?Thread?{???????????private?BufferInterruptibly?buff;???????????public?Reader(BufferInterruptibly?buff)?{???????????this.buff?=?buff;???????}???????????@Override???????public?void?run()?{???????????????try?{???????????????buff.read();//可以收到中断的异常,从而有效退出???????????}?catch?(InterruptedException?e)?{???????????????System.out.println("我不读了");???????????}?????????????????????System.out.println("读结束");???????????}???????}???????/**??*?Writer倒不用怎么改动??*/???public?class?Writer?extends?Thread?{???????????private?BufferInterruptibly?buff;???????????public?Writer(BufferInterruptibly?buff)?{???????????this.buff?=?buff;???????}???????????@Override???????public?void?run()?{???????????buff.write();???????}???????}???????public?class?Test?{???????public?static?void?main(String[]?args)?{???????????BufferInterruptibly?buff?=?new?BufferInterruptibly();???????????????final?Writer?writer?=?new?Writer(buff);???????????final?Reader?reader?=?new?Reader(buff);???????????????writer.start();???????????reader.start();???????????????new?Thread(new?Runnable()?{???????????????????@Override???????????????public?void?run()?{???????????????????long?start?=?System.currentTimeMillis();???????????????????for?(;;)?{???????????????????????if?(System.currentTimeMillis()???????????????????????????????-?start?>?5000)?{???????????????????????????System.out.println("不等了,尝试中断");???????????????????????????reader.interrupt();???????????????????????????break;???????????????????????}???????????????????????}???????????????????}???????????}).start();???????????}???}???

          这次“读”线程接收到了lock.lockInterruptibly()中断,并且有效处理了这个“异常”。好奇的读者,肯定要探个究竟,为什么ReentrantLock能做到这点,接下来,我们去迷宫探险吧……

热点排行