Java 没有公共对象的线程之间的线程间通信

Java 没有公共对象的线程之间的线程间通信,java,multithreading,queue,Java,Multithreading,Queue,我正在开发一个即时消息服务器,由于连接了n个客户端,我在任何给定时间都有n个派生线程。在任何给定的时间,任何给定的派生线程都需要能够通过发送数据的方式与任何其他派生线程通信(数据可以是任何内容,无所谓) 我研究过队列和管道的解决方案;但是,它们都依赖于一个线程(如主线程)来创建队列和/或管道对象,并将其传递给两个派生线程的构造函数。在我的场景中,我的所有线程都没有共同点,并且不共享对内存中相同对象的任何引用或类似的内容 我如何才能在两个线程之间建立某种通信通道,以显示我所描述的线程的行为?我建议

我正在开发一个即时消息服务器,由于连接了n个客户端,我在任何给定时间都有n个派生线程。在任何给定的时间,任何给定的派生线程都需要能够通过发送数据的方式与任何其他派生线程通信(数据可以是任何内容,无所谓)

我研究过队列和管道的解决方案;但是,它们都依赖于一个线程(如主线程)来创建队列和/或管道对象,并将其传递给两个派生线程的构造函数。在我的场景中,我的所有线程都没有共同点,并且不共享对内存中相同对象的任何引用或类似的内容


我如何才能在两个线程之间建立某种通信通道,以显示我所描述的线程的行为?

我建议您需要创建一个“代理”对象。线程将连接到此代理,该代理将保存对客户机的引用,以便客户机可以在其上调用回调方法。这是一种非常常见的模式,发布/订阅。

我认为,两个线程之间要共享数据,线程之间必须有某种共享对象。我认为你无法避免

所以问题变成了:当生产者和消费者彼此不了解时,如何共享一个对象

好吧,我敢打赌,在你的系统中,有一些演员/阶级/过程/任何东西同时了解生产者和消费者

class BunchOfWorkDoer {
  public void doWork() {
    BlockingQueue q = new ArrayBlockingQueue(10);
    createAndStartProducer(q);
    createAndStartConsumer(q); 
    createAndStartConsumer(q); 
  }
}
但是,如果上述方法不可行,您可以颠倒关系,让生产者和消费者“接触”并获得队列以供使用。基本模式:

// "public static" is just the simplest way to express the idea. YMMV
class Broker {
   public static BlockingQueue queue = new ArrayBlockingQueue(10);
}
// producer impl is similar, as you'd expect
class ConsumerImpl implements Runnable {
  public void run() {
    BlockingQueue queue = Broker.queue;
    // do your work
  }
}
在您描述的系统中,代理可能是一个类,它允许线程(连接)基于某个键(如用户的IM句柄)注册队列

类代理{
私有静态ConcurrentMap队列=新ConcurrentHashMap();
公共静态阻止队列findQueue(字符串名称){
返回队列。get(名称);
}
//在这个经纪人的设计中有很多选择。。。。
公共静态BlockingQueue注册表队列(字符串名称,BlockingQueue q){
返回队列。putIfAbsent(名称,q);
}
公共静态void removeQueue(字符串名称){
返回队列。删除(名称);
}
}
建立连接时,该连接的线程注册一个队列,以便其他线程可以与其通信,而想要与另一个线程通信的线程将按名称查找队列(使用代理)并通过该队列传递消息

哦,你可以考虑同步队列


这有帮助吗?

Hi,这个类在官方Java API下。如果是这样的话,它的软件包是什么?不,这更像是用来解决您描述的问题的通用软件模式。请看一个好例子。Facebook使用MQTT构建了他们的messanger产品无论您使用什么,它都必须在线程启动之前创建,并且它将是他们共同拥有的一种对象。但这有什么问题?肯定有人在启动线程,他们不是从无到有……产生一个通信器线程?我不明白同一个程序中的线程是如何被隔离的我就是那种情况?使用似乎是个好主意。是的,实际上这很有帮助。我想经纪人中的条目数量会变得相当大,所以我不确定我是否能对此做些什么
class Broker {
   private static ConcurrentMap<String,BlockingQueue> queues = new ConcurrentHashMap<>();
   public static BlockingQueue findQueue(String name) {
     return queues.get(name);
   }
   // lots of choices to make in the design of this broker ....
   public static BlockingQueue registerQueue(String name, BlockingQueue q) {
     return queues.putIfAbsent(name, q);
   }
   public static void removeQueue(String name) {
     return queues.remove(name);
   }
}