我正在开发即时消息服务器,并且由于 n 连接的客户端,我在任何给定时间都有 n 生成的线程。在任何给定的时间,任何给定的生成线程都需要能够通过发送数据与任何其他生成的线程进行通信(数据可以是任何内容,无所谓)。
我看过队列和管道的解决方案;但是,它们都依赖于诸如主要线程之类的线程来创建队列和/或管道对象,并将其传递给两个衍生线程的构造函数。在我的场景中,我的所有线程都没有任何共同之处,并且不会在内存或类似内容中共享对相同对象的任何引用。
我怎样才能在两个展示我所描述行为的线程之间建立某种沟通渠道?
答案 0 :(得分:1)
我建议你需要创建一个"经纪人"宾语。线程将连接到此代理,该代理将保存对客户端的引用,以便它可以在其上调用回调方法。这是一个非常常见的模式,发布/订阅。
答案 1 :(得分:1)
我认为,对于两个线程来共享它们之间的数据,线程之间必定存在某种共享对象。我不认为你可以避免这种情况。
所以问题就变成了:当生产者和消费者彼此不了解时如何分享对象?
好吧,我愿意下注你的系统中有某些演员/类/进程/其他知道生产者和消费者的东西。
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
}
}
在您描述的系统中,Broker可能是一个允许线程(连接)根据某个键(如用户的IM句柄)注册队列的类
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);
}
}
当建立连接时,该连接的线程注册一个队列,以便其他人可以与之通信,并且想要与另一个线程通信的线程将按名称查找队列(使用代理)并传递消息通过该队列。
哦,您可能会考虑SynchronousQueue
这有帮助吗?