synchronized (mainApp) {
         if(zoneRectangleSize < 1) 
            try {
               wait();
            } catch (InterruptedException e) { e.printStackTrace(); }
       } synchronized (mainApp) { if(zoneRectangleSize > 0) notifyAll();}

解决方案 »

  1.   

    wait() 改成 mainApp.wait()
    notifyAll() 改成 mainApp.notifyAll()
      

  2.   

    不需要吧。
    因为已经是
    synchronized(mainApp)来锁定这个对象了。
      

  3.   

    wait()和notify/notifyAll是Object的方法,不是你synchronized谁了就执行谁的方法。而是和普通其它方法一样。有对象.就执行对象的方法,无对象时执行this.方法
      

  4.   

    放完整代码吧
    你确定2段代码里的mainApp是同一个对象?
      

  5.   


    对于wait()和notify()方法
    一定要执行"被锁定对象"的这两个方法。而不是这个线程对象自己的wait()和notify()方法,
    所以你这段代码一定要改。至于改了没有用,应该是有其他原因
      

  6.   

    我想起来,
    是不是因为,我的wait()和notify()分属两个不同的线程???
    线程A notify()
    线程B wait()
      

  7.   

    package Thread;public class TwoThread {
    public static void main(String[] args) {
    Queue q=new Queue ();//new出一个q:后面的两个线程都是用的同一个q,保证一个put一个get
    Producer p=new Producer (q);//让new出的p去往q里面put
    Customer c=new Customer (q);//让new出的c从q中get
    p.start();//p和q开始的顺序并不报错
    c.start();

    }
    }
    class Producer extends Thread
    {
    Queue q;
    public Producer(Queue q) {
    this.q=q;//给成员变量赋值,再一调运q的put方法
    }
    @Override
    public void run() {
    for (int i = 0; i < 10; i++) {
    q.put(i);//此处只是让q去put  10次
    System.out.println("Producer put "+i);//并且输出本次放的是第几杯
    }
    }
    }
    class Customer extends Thread
    {
    Queue q;
    public Customer(Queue q) {
    this.q=q;//给成员变量赋值,再一调运q的get方法
    }
    @Override
    public void run() {
    while (true) {//死循环:只要q里面有,就去get
    //get方法有返回值,返回值就是producer所put的数量
    //此处也不需要去考虑是第几杯
    //在Queue中的value解决可这一问题:
    //put中的I赋给value,get方法有返回值就value的值
    System.out.println("Customer get "+q.get());
    //如果循环完了,就跳出循环,否则线程不会自己结束
    if (q.value==9) {
    break;
    }
    }

    }
    }
    class Queue
    {
    int value;
    boolean bFull=false;
    public synchronized void put (int i)//在producer中的put方法中就是将其I传进来
    {
    if (!bFull) {//条件为真(如果没满,就倒水)
    value=i;//给value赋值,现在有几杯水
    bFull=true;//满了
    notify();//唤醒其他线程(让customer去get)
    }
    try {
    wait();//告诉customer去get后自己等待customer的get结束
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    public synchronized int get()
    {
    if (!bFull) {//如果没满就等待,如果满了就不进    **这就是为什么main里面谁先开始不报错的原因**
    //get和put方法中的if条件判断起到了至关重要的作用
    try {
    wait();
    } catch (InterruptedException e) {

    e.printStackTrace();
    }
    }
    bFull =false;//赋值为没满
    notify();//唤醒producer去put
    return value;//get的返回值就是put的时候给value赋的值
    }
    }
      

  8.   


    所谓的同步肯定是在多个线程间的协调,一个线程等待某个资源而wait,另外一个线程来释放资源而notify.
    关键在于同步的资源需要是同一个。如果每个线程分别拥有自己的 mainApp 值,2个线程操作的不是一个对象,就出问题了。
      

  9.   

    A xx = new A();
    B xx = new B();两个不同类的线程对象,可以进行wait和notify操作吗?
      

  10.   

    两个不同类的线程对象,可以进行wait和notify操作,但争抢的是同一个资源。
    就像生产者与消费者一样。
      

  11.   

    说起来,我还是理论派,实际应用时,总会碰到这样那样的总是,非常感谢,但是总是还是没有解决。
    因为
    基于mainApp对象的wait和notify没有互相唤醒。
      

  12.   

    除了二楼的正确方法外.
    if(zoneRectangleSize  < 1) 要改成 while(zoneRectangleSize  < 1).
    另外这个zoneRectangleSize本身是否是同步的或volatile的?
    如果是普通变量,你在一个线程中修改为1,另一个线程中可能根本不知道它已经是1还认为是0,很可能就唤不醒.所以这个关键变量最好是volatile的,如果是同步更新它的状态比较耗性能,用volatile来标记会更好一些.