主要是实现 testthread 中创建3个线程,调用isDataChange()方法,如果数据没有改变,则线程wait,阻塞,如果数据变化,通过调用dataChange(),唤醒阻塞的线程. 发现无法唤醒线程.各位兄弟帮我看看怎么回事啊?
testthread.java
  public class testthread{
     public static void main(String args[]){
tThread tThread1 = new tThread();
tThread1.start();
tThread tThread2 = new tThread();
tThread2.start();
tThread tThread3 = new tThread();
tThread3.start();
}
 
  class tThread extends Thread{

private Notificationth  nsbd;
               public tThread(){  
initNotificationthread();
}
  private void initNotificationthread(){
try{
   nsbd = Notificationth.getInstance();
}
catch (Exception e){
e.printStackTrace();
}
}
  /**
 * Thread's run method.
 */
public void run(){
while (true){     
  if ((nsbd != null) && (nsbd.isDataChanged())) {
      System.out.print("test thread  change!");
}   
else{
    System.out.print("test thread no change!");
 break;
}
  }
}
            }
}Notificationth.javapublic class Notificationth{
   public static Notificationth manager= new Notificationth();
  public Notificationth() {


public static Notificationth getInstance()  {
   return manager;
}
public synchronized boolean isDataChanged() {
 try  { 
System.out.print("begin wait!");
wait();
System.out.print("has notify!");
// break;
}
catch (Exception ignored) {}
 
return true;
} /** 
 * <p>
 * 当服务端收到数据改变事件后,用该方法激活所有阻塞在该对象上的线程。
 * </p> 
 */
public synchronized   void   dataChanged() {
//log.info("Current Thread Name in DataChanged: " + Thread.currentThread().getName());
        notifyAll();
System.out.print("data has changed!");
}
}
testthread2.java
public class testthread2{
public Notificationth nth;
public static void main(String args[]){
Notificationth.getInstance().dataChanged();
     }
}当运行testthread.java,显示begin wait! 
我再运行testthread2.java,模拟一个数据改变的消息,发现线程无法唤醒,还是阻塞!
谢谢!

解决方案 »

  1.   

    notifyAll和wait必需在 synchronized子句中
      

  2.   

    你的两个应用程序运行于两个不同的JVM中吧!!这样怎么可能相互notify呢?
      

  3.   

    我现在都是在本地上运行,感觉notifyAll没释放了testthread的Notificationth对象上阻塞的线程,而释放的是当前的main,即在testthread2.java里调用的Notificationth.getInstance().dataChanged(),与testthread.java里Notificationth.getInstance().isdataChange()调用的是不同的Notificationth对象,但我已经声明是static了阿。
      

  4.   

    已经声明在 synchronized里了
      

  5.   

    public class testthread{
     public static void main(String args[]){
     
    tThread tThread1 = new tThread();
    tThread1.start();
     /* tThread tThread2 = new tThread();
    tThread2.start();
    tThread tThread3 = new tThread();
    tThread3.start(); */

     tThread2 th2=new tThread2();
     th2.start(); }
     
    }

    class tThread2 extends Thread{
    public tThread2()
    {}
     public void run() {
    try{sleep(5000);
    Notificationth.getInstance().dataChanged(); }
    catch (Exception ignored) {}

    }
    }
      class tThread extends Thread{

    private Notificationth  nsbd;
                    int i=0;
    public tThread()
    {
     
    initNotificationthread();
    }
      private void initNotificationthread(){
    try {
    nsbd = Notificationth.getInstance();
    }
    catch (Exception e){
    e.printStackTrace();
    }
    }
     
    /**
     * Thread's run method.
     */
    public void run()
    {
    /* while (true)
    {    */ 
      if ((nsbd != null) && (nsbd.isDataChanged()))
    {
     
    System.out.print("test thread  change!");


     
    else
    {
        System.out.print("test thread no change!");
    //  break;
    // sleep for some time before creating the
    // NotificationServiceBusinessDelegate.

    // gotoSleep();
    // initNotificationthread();
    }

    // }
    } }
    但在同一个java中调用Notificationth.getInstance().isdataChange()就可以实现notifyAll,而在不同的java中运行就不可以notifyAll,而Notificationth.getInstance()是同一个对象阿.怎么不能唤醒阻塞的线程?
      

  6.   

    呵呵,谢谢旗鲁特!,多线程我用的少。主要是现在需要做个web services,为了提高服务的运行效率,不会每次都访问服务端方法,而是只在服务端数据变化时,才进行soap调用.思想是客户端先getallmsg(信息持久化在本地,一般以后都在本地进行数据操作,除非发现数据有变化)同时设置个客户端的调用notification的服务,服务端通过isdataChange将线程阻塞,服务调用一直处于active状态,当发现有客户更新数据后,调用datachange再唤醒客户端线程。比如:有客户调用服务端addstock(),更新数据,在addstock中设置监听,如果增加数据成功,即调用datachange唤醒阻塞的线程.完成服务调用.
    如何通过多线程实现了吗?客户端我设计成一个swing的GUI.