Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 不共享公共资源的线程是否可以基于线程id/名称进行通知?_Java_Multithreading_Wait_Notify - Fatal编程技术网

Java 不共享公共资源的线程是否可以基于线程id/名称进行通知?

Java 不共享公共资源的线程是否可以基于线程id/名称进行通知?,java,multithreading,wait,notify,Java,Multithreading,Wait,Notify,如果我知道要通知的线程的ID,并且不共享其他公共资源,我可以通知它吗? 两个线程都是由同一个应用程序启动的 另一个线程使用thread.currentThread().wait(500)进入等待状态 是-但必须停止使用等待 该技术是维护一个映射,其中包含正在运行的每个线程的队列。字符串键是线程ID 如果希望线程暂停,请使用而不是wait。你只需要在队列中放入一些东西来唤醒线程,显然,如果你知道线程的ID,你可以很容易地从映射中获得它的队列,只要它在同一个线程组中,您可以使用遍历所有线程,并根据给

如果我知道要通知的线程的ID,并且不共享其他公共资源,我可以通知它吗? 两个线程都是由同一个应用程序启动的


另一个线程使用thread.currentThread().wait(500)进入等待状态

是-但必须停止使用
等待

该技术是维护一个
映射
,其中包含正在运行的每个线程的队列。
字符串
键是线程ID


如果希望线程暂停,请使用而不是
wait
。你只需要在队列中放入一些东西来唤醒线程,显然,如果你知道线程的ID,你可以很容易地从
映射中获得它的
队列
,只要它在同一个线程组中,您可以使用遍历所有线程,并根据给定线程的id查找该线程,然后执行通常的同步和.notify()


提供对所有线程进行迭代的其他方法。

您可能只希望通知等待同一锁的线程。不要使用当前线程对象作为锁,这没有帮助。一旦一个线程被唤醒,你需要检查一个条件来防止虚假的唤醒。如果您确定只有一个线程在锁上等待,那么调用lock对象上的notify应该会唤醒等待的线程。

您可以为线程提供一些用于通信的公共对象,因此您不必依赖于线程名称

例如:

class Notifier extends Thread {
    private final Object common;

    Notifier(Object common) { this.common = common; }

    public void run() {
        // do work
        synchronized (common) { common.notify(); }
    }
}

class Waiter extends Thread {
    private final Object common;

    Waiter(Object common) { this.common = common; }

    public void run() {
        // do work
        synchronized (common) { common.wait(TIMEOUT); }
    }
}

更好的方法是使用
java.util.concurrent.CountDownLatch
实现同样的效果。

是的,这是可能的。但它丑陋、潜在脆弱和/或效率低下

正如@nos所说,您可以使用
Thread.enumerate()
枚举
Thread组中的
Thread
对象,测试每一个对象,直到找到具有预期名称和/或线程id的线程。如果组中有大量线程,这显然是低效的

脆弱性表现在以下几个方面:

  • 具有给定名称或id的线程可能不再存在
  • 可能有多个同名线程
  • 线程id值最终将在有足够的线程被删除后被回收
在同步方面

  • 可以想象,应用程序(或库代码)的其他部分可能会在线程对象上使用wait/notify进行同步,因此可能会收到不需要的通知
  • 在某些Java平台上,(至少在历史上)可以获得自发的通知。。。因此,在不测试共享条件变量的情况下使用wait/notify可能会导致错误的同步

在我看来,最好创建可以等待/通知的(私有)对象,并使用适当的条件变量。或者,如果没有吸引力,请使用现有的更高级别并发类之一进行同步。

考虑到所涉及的两个线程在代码的不同部分启动,因此它们之间都没有太多的链接,这是否意味着我必须转到主启动文件,并将一个对象传递给这两个线程?我猜您希望一个线程通知另一个线程,因为一个线程的操作取决于另一个线程的上一个操作。您需要有一个用于线程间通信的公共锁。如果两个线程根本不相关,那么为什么它们之间不需要任何协调。实际上我的问题与此相关,这里的其中一个线程只是一个侦听线程,如果它接收到特定类型的数据包,它应该通知另一个线程。。。到目前为止,我想我必须使用一个公共资源。你不需要通知线程-你需要通知对象的服务员。但是,您可以中断特定线程。使用blockingqueue比等待/通知任何常规对象有什么好处吗?@Sam-是!它更加灵活,可以正确处理等待/通知系统中固有的所有边缘条件。在我看来,使用Wait/Notify无法正确处理一个新的java.util.concurrent对象。我喜欢这个答案,但我想区分它从另一个线程接收信号(作为队列的一部分)和轮询时的情况,并相应地执行不同的代码,我不能那样做,你能提出什么建议吗?这是我真正的问题。。!