自定义消息传递信号量?

时间:2013-10-11 11:52:30

标签: java multithreading data-structures concurrency synchronization

假设我有两个主要运行线程A和B,以及一个异步调用的线程T.我希望线程A等到在线程T上收到消息aMsg并且线程B停止直到在线程上收到消息msgB T.我知道如何用2个sempahores做到这一点:

sempahoreA = new Sempahore(0);
sempahoreB = new Sempahore(0);

//in thread A
//code until where to run 
semaphoreA.acquire()

//in thread B
//code until where to run 
semaphoreB.acquire()

//in thread T
if (msgA.equals(msgRecevied)) {
    semaphoreA.release()
} 
if (msgB.equals(msgReceived)) {
    semaphoreB.release()
}

问题是我有多个A,B,C,...线程,我不想使用多个信号量。在java.util.concurrent中的某个类是否可以用一个实例替换所有信号量?

synchronizer = //?

//in thread A
//code until where to run 
synchronizer.acquire(msgA)//only let go if msgA is received from thread calling release

//in thread B
//code until where to run 
synchronizer.acquire(msgB)//only let go if msgA is received from thread calling release

//in thread T
if (msgA.equals(msgRecevied)) {
    synchronizer.release(msgA)
} 
if (msgB.equals(msgReceived)) {
    synchronizer.release(msgB)
}//actually here you can call synchronizer.release(msgReceived)

1 个答案:

答案 0 :(得分:1)

伟大的直觉m3th0dman。我认为你所寻找的是Transfer Queue

这是一个生产者可能等待消费者接收的BlockingQueue 在你的情况下,线程A和B是生成器,线程T是唯一的 消费者。

简而言之:

  1. 创建共享TransferQueue<Object> synchronizer = new TransferQueue<>();
  2. 主题A和B调用阻止方法synchronizer.transfer(new Object());
  3. 与此同时,Thread t在闲暇时调用synchronizer.take();来取消阻止。
  4. 以下是一个例子:

    import java.util.concurrent.TransferQueue;
    
    public class TransferQueueExample {
        public static void main(String[] args) {
            final TransferQueue<Object> synchronizer = new TransferQueue<>();
    
            for (int i = 0; i < 10; i++) {
                final Thread t = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        // Do work until
                        // ...
                        System.out.println("Thread " + i + " is transferring.");
    
                        synchronizer.transfer(new Object()); // This is blocking
                        System.out.println("Thread " + i + " done transferring.");
                    }
                }).start();
            }
    
            final Thread consumer = new Thread(new Runnable() {
                @Override
                public void run() {
                    // TODO: Note thatthis will run indefinitely so in a real
                    // scenario, find a way of shutting this thread down.
                    while (true) {
                        System.out.println("There are about " +
                                           synchronizer.getWaitingConsumerCount()
                                           + " threads waiting");
                        synchronizer.take();
                        System.sleep(1000);
                    }
                }
            }).start();
        }
    }
    

    我希望嵌套和匿名课程不会分散注意力。