当前位置: 代码迷 >> J2SE >> notify有关问题
  详细解决方案

notify有关问题

热度:2285   发布时间:2013-02-25 00:00:00.0
notify问题
代码这样的
Java code
package com.tdt.test;public class NotifyTest {    public static final String LOCK="LOCK_MAIN";        public static void main(String[] args) {        for(int i=0;i<=10;i++){            new Work("线程"+i).start();        }        for(int i=0;i<=10;i++){            synchronized (LOCK) {                LOCK.notify();                try {                    Thread.sleep(1000);                } catch (Exception e) {                    e.printStackTrace();                }            }                    }    }}class Work extends Thread{        public Work(String threadName) {        super(threadName);    }        @Override    public void run() {        synchronized (NotifyTest.LOCK) {            try {                NotifyTest.LOCK.wait();            } catch (Exception e) {                e.printStackTrace();            }        }        System.out.println(Thread.currentThread().getName()+"得到通知.........");    }}

我是想看看notify最后是不是都通知到了
这段代码放到锁外面,运行没问题,线程后面执行完了
Java code
try {     Thread.sleep(1000);} catch (Exception e) {   e.printStackTrace();}

放到里面后
线程10感觉一直处于等待当中,没有得到通知

------解决方案--------------------------------------------------------
因为wait的时候,线程释放掉当前持有的锁,当从wait中醒来的时候,需要重新获取之前释放的锁

然而,Thread.sleep(1000)期间,notify的那个线程,一直持有该锁,导致wait一直获取不到锁,所以它还得等
------解决方案--------------------------------------------------------
个人觉得:
程序要执行完的话,一定是wait()在先,notify()在后。这样保证能够唤醒等待的线程。
根据测试的情况看,把那段等待的程序放在同步块里的话,在等待时,就象楼上所说,是不释放锁的。这样会导致Work线程得到锁的几率大大减小。notify()先于wait()都执行完了,那么后面运行的线程的wait()就没有机会唤醒了。
而如果把那段程序放在外面的话,主线程占有锁的时间大大缩短,而work线程得到所得几率大大增加,10个线程会先于主线程启动完(运行到wait()). 这些进入等待的线程都会得到主线程的notify()唤醒。会执行完。
楼主可以加一句测试是一下:
Java code
    @Override    public void run() {        synchronized (NotifyTest.LOCK) {            try {                System.out.println("****");   //这加一句看看效果。                NotifyTest.LOCK.wait();            } catch (Exception e) {                e.printStackTrace();            }        }        System.out.println(Thread.currentThread().getName()+"得到通知.........");    }
  相关解决方案