我在现实生活中遇到了一个有趣的问题。我把问题简化到了这里:
设计两个方法A()和方法B()。每种方法都可以被认为是产生元素原子(A或B)。化合物A [N] B [M]需要N个A原子和M个B原子。
在我们有N个A原子和M个B原子之前,每个对A()和B()的调用都将被阻止。当我们到达N个A原子和M个B原子时,第一个N A()调用和第一个M B()调用将返回。例如,如果我进行N + 2个A()调用并遵循M B()调用,则将返回前N A()个调用和所有M B()调用。将有2个A()呼叫被阻止?
我该如何解决这个问题?我正在使用Java。
答案 0 :(得分:1)
您可以使用 BlockingQueues :
static class AtomA
{
}
static class AtomB
{
}
static class ChemicalCompound
{
BlockingQueue<AtomA> as = new LinkedBlockingQueue<AtomA>();
BlockingQueue<AtomB> bs = new LinkedBlockingQueue<AtomB>();
public ChemicalCompound(int na, int nb)
{
while (na-- != 0) as.add(new AtomA());
while (nb-- != 0) bs.add(new AtomB());
}
public AtomA A() throws InterruptedException
{
return as.take();
}
public AtomB B() throws InterruptedException
{
return bs.take();
}
}
public static void main(String[] args) throws Exception
{
final ChemicalCompound cc = new ChemicalCompound(2, 3);
Thread ta = new Thread(new Runnable(){
@Override
public void run()
{
while (true)
{
try
{
cc.A();
System.out.println("Got a A!");
Thread.sleep(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
});
ta.start();
Thread tb = new Thread(new Runnable(){
@Override
public void run()
{
while (true)
{
try
{
cc.B();
System.out.println("Got a B!");
Thread.sleep(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
});
tb.start();
ta.join();
tb.join();
return;
}
Thread.sleep 仅用于演示可能的线程交错,但当然“在生产中”将其删除。
结果:
Got a A!
Got a B!
Got a A!
Got a B!
Got a B!