/******I have build a GUI for the popurse that when I click the checkbox 
              button,the corresponding thread will suspend or wake up.But it doesn't 
              come out with the expected result.Please help~***********************/  
        
 class itemStateChangedHandler implements ItemListener {
                      public void itemStateChanged(ItemEvent e){
                     JCheckBox jcheckbox=(JCheckBox)e.getItem();
                     String s=jcheckbox.getText();
                     //System.out.println(s);
                     if(jcheckbox.isSelected()==true){
                     try{
                      switch (s) {
                 case "线程1挂起":synchronized (t1) {
                 t1.wait();
                 }break;
                 case "线程2挂起":synchronized (t2) {
                 t2.wait();
                 }break;
                 case "线程3挂起":synchronized (t3) {
                 t3.wait();
                 }break;
                 }
                 }
                      catch(InterruptedException ex){
                      //don't do anything
                      }
                      }
                    
                     else{
                      switch (s) {
                 case "线程1挂起":synchronized (t1) {
                 t1.notify();
                 }break;
                 case "线程2挂起":synchronized (t1) {
                 t1.notify();
                 }break;
                 case "线程3挂起":synchronized (t1) {
                 t1.notify();
                 }break;
                 }
                     }
                     }
                    }

解决方案 »

  1.   


        wait() - Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.    notify() - Wakes up a single thread that is waiting on this object's monitor.1. Using a local Thread variable prevents other threads invoking the run() method on your object. Only the thread represented by this object instance can use the run() method. It is generally bad practice to invoke the run() method of a Thread manually from a different Thread, but certainly possible.2. This point needs to be explained in the context of point 1. This part also considers the case when interval is very long, and the thread needs to be stopped ASAP.
    You certainly need to nullify the reference because otherwise the code in part 1 will just continue looping. But consider what may happen if you simplify the stop method to:public void stop() {
        waiter.interrupt();
        waiter = null;    
    }Since this is executed from another thread, it can be intertwined with the run() method in any way. For example, threadA calls stop() to stop threadB which is in run():    threadB: sleep(interval)
        threadA: waiter.interrupt()
        threadB: caught InterruptedException
        threadB: call to repaint
        threadB: enter next while cycle
        threadB: enter sleep(interval)
        threadA: waiter == nullIn this case, instead of immediately stopping, threadB does another cycle of sleeping, which fails the set task of stop a thread that waits for long periods. In the given implementation you first nullify, then interrupt, which prevents this kind of behaviour.3. In short: Because another thread may have notified your code, without setting the correct flag. The general contract of notify() is that it is harmless to call (but a useless call will obviously consume some resources). All threads are supposed to be able to cope with spurious wake-ups.
      

  2.   

    for example, when it's running t1.wait();, can the running thread ,if it's t1,  be suspended?
      

  3.   

    When I call the method t1.wait(),it(t1) will not be suspended?why
      

  4.   

    When I call the method t1.wait(),it(t1) will not be suspended?why 
      

  5.   


    does the current thread  own this object's monitor?or can you first simplify your code situation? 
    test if it works using the following idiom.synchronized (obj) {
             while (<condition does not hold>)
                 obj.wait(timeout);
             ... // Perform action appropriate to condition
         }