2012-04-08 75 views
1

我正在通过线程,并且我读取了.. notify()方法用于向同一对象的等待池中正在等待的线程中的一个且仅有一个线程发送信号。 notifyAll()方法的工作方式与notify()方法相同,只是它将信号发送给等待对象的所有线程。线程拒绝通知

现在我的问题是,如果我们说我有5个线程在等待并通过Notify(),我想发送通知给线程3,那么通知发送到线程3时应该有什么逻辑。 !

+0

您可以在列表中持有对所有'Thread'对象的引用,并遍历它们直到找到所需的对象,并在该Thread上调用'notify()'。 – 2012-04-08 16:49:20

+0

嗨,亨特,非常感谢,请你通过一个小代码来展示,这将是一个很好的帮助.. !!非常感谢.. !! – user1320527 2012-04-08 16:52:54

+0

嗨,猎人,惊人的逻辑,请如果这将是一个很大的帮助,如果你可以请显示小演示,事情会更清晰..!非常感谢..!! – user1320527 2012-04-08 16:58:04

回答

4

你不能直接用waitnotify来做到这一点。你必须在某个地方设置一个标志,让线程中的代码检查它并返回到等待它是否是错误的线程,然后调用notifyAll

请注意,如果您必须处理此问题,则可能表示您应该重构代码。如果你需要能够通知每个单独的线程,你应该让每个线程都等待一个不同的对象。

+0

你好泰蒙,非常感谢,但你能告诉我一个小程序,其中说5线程或更多的等待,并通过notif()你发送通知线程3只...你的选择..这将是一个很好的帮助.. !!非常感谢.. !! – user1320527 2012-04-08 16:51:01

+0

嗨泰缅,非常感谢,但请你给我看一个小程序,其中说5线程或更多的等待,并通过notif()你发送通知线程3只...你的选择...这将是一个很好的帮助.. !!非常感谢.. !! - user1320527 10小时前 – user1320527 2012-04-09 02:55:29

+0

Jiri Patera的回答提供了一个标志方法的例子。 – Taymon 2012-04-09 03:39:17

2

wait-notify是一个较低级别的机制来向其他线程指示事件(预期发生)。这是生产者/消费者机制的例子。

这不是线程彼此通信的机制。
如果你需要这样的东西,你看错了方向。

0

下面的代码启动五个线程,并设置第三个标志,告诉它它是唯一继续。然后通知所有等待同一个锁对象lock的线程(唤醒),但只有选中的一个继续。要小心,编写多线程应用程序并不容易(正确同步,处理虚假唤醒等)。您不应只需从组中唤醒一个特定线程,因为这指向不正确的问题分解。总之,在这里你去...

 

package test; 

public class Main { 

    public static void main(String[] args) { 
    Main m = new Main(); 
    m.start(5); 
    } 

    private void start(int n) { 
    MyThread[] threads = new MyThread[n]; 
    for (int i = 0; i < n; i++) { 
     threads[i] = new MyThread(); 
     /* set the threads as daemon ones, so that JVM could exit while they are still running */ 
     threads[i].setDaemon(true); 
     threads[i].start(); 
    } 
    /* wait for the threads to start */ 
    try { 
     Thread.sleep(500); 
    } catch (InterruptedException ex) { 
     ex.printStackTrace(); 
    } 
    /* tell only the third thread that it is able to continue */ 
    threads[2].setCanContinue(true); 
    /* wake up all threads waiting on the 'lock', but only one of them is instructed to continue */ 
    synchronized (lock) { 
     lock.notifyAll(); 
    } 
    /* wait some time before exiting, thread two should be able to finish correctly, the others will be discarded with the end of the JVM */ 
    for (int i = 0; i < n; i++) { 
     try { 
     threads[i].join(500); 
     } catch (InterruptedException ex) { 
     ex.printStackTrace(); 
     } 
    } 
    System.out.println("Done!"); 
    } 

    /** synchronization object, i.e. a lock which makes sure that only one thread can get into "Critical Section" */ 
    private final Object lock = new Object(); 

    /** A simple thread to demonstrate the issue */ 
    private final class MyThread extends Thread { 
    private volatile boolean canContinue; 
    @Override 
    public void run() { 
     System.out.println(Thread.currentThread().getName() + " going to wait..."); 
     synchronized (lock) { 
     while (!canContinue) { 
      try { 
      lock.wait(1000); /* one second */ 
      } catch (InterruptedException ex) { 
      ex.printStackTrace(); 
      } 
     } 
     } 
     System.out.println(Thread.currentThread().getName() + " woken up!"); 
    } 
    public void setCanContinue(boolean canContinue) { 
     this.canContinue = canContinue; 
    } 
    }; 
} 
 

代码的输出是:

 
Thread-0 going to wait... 
Thread-2 going to wait... 
Thread-3 going to wait... 
Thread-1 going to wait... 
Thread-4 going to wait... 
Thread-2 woken up! 
Done! 

所以,你可以清楚地看到,只有第三个线程(从0开始索引)被唤醒。您必须更详细地研究Java同步和多线程,以了解代码的每一行(例如,here)。

我想帮助你更多,但我将不得不写几乎一本关于Java线程的书,这就是为什么我只是指出这个Java Tutorial on threads。你是对的,这个问题并不容易,特别是对初学者来说。所以我建议你阅读参考教程,然后你应该能够理解上面的大部分代码。有没有简单的方法或至少我不知道任何。

+0

嗨Jiri,能否请你解释一下上面的程序bi,这样它可以帮助理解得更清楚,并且也可以通知单线程,就像我上面写的那样,我们只想通知线程3 .. 。! – user1320527 2012-04-10 02:30:39

+0

嗨日日能请你提供这个简单的例子,因为它是在很高的水平,像我这样的初学者这是非常艰难的.. !!在此先感谢.. !! – user1320527 2012-04-10 17:49:24

+0

如果你能以相似的方式解释同样的事情,但通过简单的术语.. !!这将是伟大的..这将是一个很大的帮助,并明确更多的理解.. !!在此先感谢.. !! – user1320527 2012-04-10 18:05:29