首先你的概念不是很清楚。被声明为synchronized的方法里不一定要有notify方法。
synchronized表示该程序段为排他访问的,是解决代码冲突问题的。比如:
有两个进程同时(或先后)对同一方法提出访问,而该方法中有排他的要求就必须加上synchronized字段。
wait和notify、notifyall是为了控制共享对象的访问的,典型的例子是生产者和消费者的例子:(该例子也用了synchronized)
生产者生产的产品要放到仓库中,消费者从仓库中取产品去消费,而仓库的容量是有限的。生产者在生产一个产品放到仓库中前要判断仓库是否已满,如果已满则要wait()仓库对象,消费者取走一个产品时要notify仓库对象。而对仓库容量的增减语句段就是synchronized的了。

解决方案 »

  1.   

    1、所有Object对象都有wait()方法,它是使当前线程等待,直到被其他线程调用notify()或者notifyAll()方法2、线程同步的就是synchronized,但线程的方法不止你写的这么多,还有其他的如sleep,yield等方法,还有线程组等等。你要想熟练,最好的方法就是多写一些线程的程序。
      

  2.   

    public final void wait()
                    throws InterruptedException
        Causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0). 
        引起当前线程等待,进入队列。直到另一个线程调用对象的notify或者notifyAll方法。此方法的功能相当于仅仅执行了wait(0)方法。
    ----------------------------------------------------------------------
    public final void notify()
        Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods. 
        唤醒队列中的一个线程。
      

  3.   

    thank qlampskyfaceto hq1305018(跃强):那你说synchronized方法里,有notify的是什么时候,不需要notify的是什么时候。我倒觉得,如果当前线程调用notify的话,仅仅说明当前线程让位于队列中的线程。
              如果当前线程调用wait的话,仅仅说明当前线程进入队列。只有当两个方法一起使用的话,例如先notify再wait,才说明,当前线程让位于队列中线程,且自己再次进入队列,但是当它调用notify完毕后,它已经不是当前线程了,所以,在一个synchronized方法中,一个线程不可能一次完成先notify后wait的动作。
    那如果是先wait再notify呢?你想想,也是不可能的。那么在一次操作里,一个线程要么只完成notify,要么只完成wait。可是,为什么有的synchronized方法里有,有的没有呢?
      

  4.   

    可不可以这么说呢?如果方法里调用了notify呢,就会在队列中得到另一个线程如果没有调用notify,那么队列中的线程就不会被调用,就一直在wait,直到有notify为止
      

  5.   

    synchronized方法可以锁定对象,使对象拥有一个lock,其他对象调用这个同步对象时,必须得到这个lock.其他对象如果要操作这个同步对象,必须等lock释放后才能执行.
    wait()方法使该同步对象锁死,而notify释放这个同步对象的lock.而notify释放的lock没有指向性,如果同时有几个lock,则有JVM选择其中一个来释放,而notifyall可以释放所有的lock.因此需优先使用notifyall.另外,你可以参考practical java一书,这本书对于多线程有很好的解释.
      

  6.   

    to wushicnn(虎猫) :释放所有的lock有什么用啊?释放所有的lock和释放一个lock有什么区别啊?
      

  7.   

    To xiaozuidazhi:
    调用wait()方法会使当前线程进入等待池,但要注意的是等待池是与某个具体对象有关的,而不是所有线程都在一个等待池中。
    调用notify()方法或notifyAll()方法是对某个具体对象使用的,notify()方法会释放该对象的等待池中的一个线程,notifyAll()方法会释放该对象的等待池中的所有对象。但要注意的是某个线程调用过notify()方法或notifyAll方法后不一定会“让位”也会继续执行的。
    sychronized()方法与wait()、notify()、notifyAll()没有必然的联系,你为什么非要把他们联系到一起考虑呢?
      

  8.   

    请问当方法被声明为synchronized时,为什么方法里有时候有notify和wait有时候却没有,为什么不加上呢?当方法已经被声明了 synchronized 时,为什么要有 notify和wait 啊??synchronized 加到方法上时,简单的说,就是同时该方法只能在一个线程中执行!!
    必须在该方法执行完成之后才能在其他的线程中执行!!
      

  9.   

    to hq1305018(跃强) :notifyAll固然能释放某对象等待池中所有线程,但是这所有线程还是只有一个进入临界区啊,那么为什么还要释放等待池中所有线程,而不只释放一个线程,更有甚者,还有人说优先使用notifyAll,优先使用还有个什么劲呀???
    既然“某个线程调用过notify()方法或notifyAll方法后不一定会“让位”也会继续执行的”,那么为什么还要调用notify等方法唤醒等待池中的线程呢?-----------------------------------唤醒的目的是让别人进来,既然自己都没有出去,别人还怎么进来呢?
      

  10.   

    有谁能深层次得说一说notify和wait到底有什么用?
      

  11.   

    说简单点,就是wait()方法挂起一个线程,并且把这个线程所占有的锁释放notify()和notifyAll()就是唤醒指定的正在WAIT中的线程或全体WAIT中的线程,让线程重新取得锁
      

  12.   

    To xiaozuidazhi:
    1、notifyAll固然能释放某对象等待池中所有线程,但是这所有线程还是只有一个进入临界区啊,那么为什么还要释放等待池中所有线程,而不只释放一个线程,更有甚者,还有人说优先使用notifyAll,优先使用还有个什么劲呀???
    答:在notifyAll()之后,释放了N个线程,但并不是N-1个线程会返回等待池,只要能满足N个线程中的M个线程执行的条件,那么这M个线程都会执行的。“临界区”并不是等待池,sychronized的临界区某一时刻只有一个线程在,但和等待对象可用不是一个概念。例如消费者和生产者例子,如果生产者一次能生产3个产品而消费者一次消费1个产品,那么如果仓库对象为空造成的消费者在等待池中等待,而生产者的notifyAll()调用会使3个消费者线程执行,而其它消费者线程继续等待。但在3个消费者线程去执行“仓库容量减1”这个操作时一定要sychronized,你懂了吗?
    2、既然“某个线程调用过notify()方法或notifyAll方法后不一定会“让位”也会继续执行的”,那么为什么还要调用notify等方法唤醒等待池中的线程呢?
    答:这个问题就更不对了,调用notify()方法的线程和被唤醒的线程完全可以同时运行啊?
      

  13.   

    xiaozuidazhi:
    同情中,这个确实很难弄懂,你可以看看如下的例子:
    本例子实现了两个线程,每个线程输出1到100的数字。
    第一个线程输出1-10,停止,通知第二个线程 输出1-10 第二个线程停止 通知第一个线程 输出11-20 ...
    实现的要点是
    在Java中,每个对象都有个对象锁标志(Object lock flag)与之想关联,当一个线程A调用对象的一段synchronized代码时,
    它首先要获取与这个对象关联的对象锁标志,然后执行相应的代码,执行结束后,把这个对象锁标志返回给对象;因此,在线程A执行
    synchronized代码期间,如果另一个线程B也要执行同一对象的一段synchronized代码时(不一定与线程A执行的相同),它将
    要等到线程A执行完后,才能继续....如何利用wait() notify() notifyAll()?在synchronized代码被执行期间,线程可以调用对象的wait()方法,释放对象锁标志,进入等待状态,并且可以调用notify()或者
    notifyAll()方法通知正在等待的其他线程。notify()通知等待队列中的第一个线程,notifyAll()通知的是等待队列中的所有线程。 
      
    package jdeveloper.study;/**
     * Title:        Jdeveloper's Java Projdect
     * Description:  n/a
     * Copyright:    Copyright (c) 2001
     * Company:      soho  http://www.ChinaJavaWorld.com
     * @author [email protected]
     * @version 1.0
     */
    import java.lang.Runnable;
    import java.lang.Thread;public class DemoThread implements Runnable{  public DemoThread() {
             TestThread testthread1 = new TestThread(this,"1");
             TestThread testthread2 = new TestThread(this,"2");         testthread2.start();
             testthread1.start();
      }  public static void main(String[] args) {
        DemoThread demoThread1 = new DemoThread();  }
       public void run(){        TestThread t = (TestThread) Thread.currentThread();
            try{
              if (!t.getName().equalsIgnoreCase("1")) {
                  synchronized(this) {
                      wait();
                  }
              }
              while(true){            System.out.println("@time in thread"+ t.getName()+ "="+ t.increaseTime());            if(t.getTime()%10 == 0) {
                  synchronized(this) {
                    System.out.println("****************************************");
                    notify();
                    if ( t.getTime()==100 ) break;
                    wait();
                }
              }
            }
            }catch(Exception e){e.printStackTrace();}
        }}class TestThread extends Thread{
        private int time = 0 ;
        public TestThread(Runnable r,String name){
          super(r,name);
        }
        public int getTime(){
           return time;
        }
        public int increaseTime (){
           return ++time;
        }
      

  14.   

    在wait后一定要用notifyAll(),这在Core Java下册讲的很清楚了
      

  15.   

    要用notifyAll,当然在只要一个线程被wait时,用notify就可以了.但如果有多个wait的话,就必须使用notifyAll,因为使用notify,你不知道到底哪一个线程被解锁.所以必须使用nitifyAll,其实这样并没有什么坏处,因为解锁后的线程,如果不满足条件,那些线程仍会进入wait状态,而你需要解锁的那个线程就会如你所愿了