程序如下:
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,如需转载请自行联系原作者