程序如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | public ?static ?void ?main(String[]?args)? throws ??Exception{ ???? final ?List?list?=? new ?ArrayList(); ???? final ?Object?lock?=? new ?Object(); ???? Thread?t1?=? new ?Thread( new ?Runnable()?{ ???????? @Override ???????? public ?void ?run()?{ ???????????? synchronized ?(lock){ ???????????????? for ( int ?i?=? 0 ?;?i?<? 10 ?;?i++){ ???????????????????? list.add(i); ???????????????????? if (list.size()?==? 5 ){ ???????????????????????? lock.notify(); ???????????????????????? System.out.println(Thread.currentThread().getName()?+? "發出通知!" ); ???????????????????? } ???????????????? } ???????????? } ???????????? System.out.println(Thread.currentThread().getName()?+? "execute?over!" ); ???????? } ???? }); ???? Thread?t2?=? new ?Thread( new ?Runnable()?{ ???????? @Override ???????? public ?void ?run()?{ ???????????? synchronized ?(lock){ ???????????????? if (list.size()?!=? 5 ){ ???????????????????? try ?{ ???????????????????????? lock.wait(); ???????????????????? }? catch ?(InterruptedException?e)?{ ???????????????????????? e.printStackTrace(); ???????????????????? } ???????????????? } ???????????????? System.out.println(Thread.currentThread().getName()?+? "?收到通知!" ); ???????????? } ???????????? System.out.println(Thread.currentThread().getName()?+? "execute?over!" ); ???????? } ???? }); ???? t2.start(); ???? Thread.sleep( 1000 ); ???? t1.start(); } |
分析:
程序的意圖本是利用多線程之間的通信,利用wait/notify實現,可是運行的結果是雖然線程T1發出了通知,但是線程T2并沒有立即收到通知進行執行,這是為什么呢??因為只有線程T1執行完畢釋放了鎖,T2才能執行,那么也就是說wait/notify并不是實時的(wait釋放了鎖,而notify沒有釋放鎖導致的),那么線程之間實時的通信該怎么做呢?可以利用CountDownLatch來實現。
對程序的改進:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | public ?static ?void ?main(String[]?args)? throws ??Exception{ ???? final ?List?list?=? new ?ArrayList(); ???? final ?Object?lock?=? new ?Object(); ???? final ?CountDownLatch?countDownLatch?=? new ?CountDownLatch( 1 ); ???? Thread?t1?=? new ?Thread( new ?Runnable()?{ ???????? @Override ???????? public ?void ?run()?{ ???????????????? for ( int ?i?=? 0 ?;?i?<? 10 ?;?i++){ ???????????????????? list.add(i); ???????????????????? if (list.size()?==? 5 ){ ???????????????????????? countDownLatch.countDown(); ???????????????????????? System.out.println(Thread.currentThread().getName()?+? "發出通知!" ); ???????????????????? } ???????????????? } ???????????? System.out.println(Thread.currentThread().getName()?+? "execute?over!" ); ???????? } ???? }); ???? Thread?t2?=? new ?Thread( new ?Runnable()?{ ???????? @Override ???????? public ?void ?run()?{ ???????????????? if (list.size()?!=? 5 ){ ???????????????????? try ?{ ???????????????????????? countDownLatch.await(); ???????????????????? }? catch ?(InterruptedException?e)?{ ???????????????????????? e.printStackTrace(); ???????????????????? } ???????????????? System.out.println(Thread.currentThread().getName()?+? "?收到通知!" ); ???????????? } ???????????? System.out.println(Thread.currentThread().getName()?+? "execute?over!" ); ???????? } ???? }); ???? t2.start(); ???? Thread.sleep( 1000 ); ???? t1.start(); } |
本文轉自zfz_linux_boy 51CTO博客,原文鏈接:http://blog.51cto.com/zhangfengzhe/1875221,如需轉載請自行聯系原作者