如何在java中实现在一个方法中等待另一个方法完成?
我有一套方法,比如说如何在java中实现在一个方法中等待另一个方法完成?,java,Java,我有一套方法,比如说m1,m2,m3,m4。每个方法都需要等待前面的方法完成。如果我调用m3,它必须等待m2。我考虑过在每个方法中使用flag,如果完成了标记的话。但是对于通知,如果m1说notify(),我只希望此通知用于m2,而不用于其他等待方法 我有一个组件a,它有m1,m2,m3作为输入方法,m4作为输出方法。一旦m3发生,它将调用m4生成输出。但是m1,m2,m3必须按顺序执行,并且可以从不同的类调用。等待和相应的信号必须在那里 我该如何实现它呢?我会将计数器设置为int,每个方法都必
m1
,m2
,m3
,m4
。每个方法都需要等待前面的方法完成。如果我调用m3
,它必须等待m2
。我考虑过在每个方法中使用flag,如果完成了标记的话。但是对于通知,如果m1
说notify()
,我只希望此通知用于m2
,而不用于其他等待方法
我有一个组件a
,它有m1
,m2
,m3
作为输入方法,m4
作为输出方法。一旦m3
发生,它将调用m4
生成输出。但是m1
,m2
,m3
必须按顺序执行,并且可以从不同的类调用。等待和相应的信号必须在那里
我该如何实现它呢?我会将计数器设置为int,每个方法都必须等到计数器达到它们的数字后才能执行。这样,每个方法只需增加计数器,您可以在以后插入更多计数器。一个简单的解决方案是只使用四个不同的锁对象。(或者确实在同一线程中运行它们,但这可能不是您想要的。)
再详细一点,可能会有一个更优雅的解决方案。阻塞队列可能会有所帮助,但如果您使用的是ThreadPoolExecutor,则不会。ThreadPoolExecutor没有现成的解决方案在队列已满时进行阻止(这是executor的一部分,不是队列的函数,因为executor使用BlockingQueue.offer,它从不阻止,如果队列已满,则使用RejectedExecutionHandler)。您可以实现自己的RejectedExecutionHandler,该处理程序会一直阻塞,直到它可以将内容放入队列,但这里有一种快速确定锁的方法:
ReentrantLock l1 = new ReentrantLock();
ReentrantLock l2 = new ReentrantLock();
ReentrantLock l3 = new ReentrantLock();
l1.lock();
l2.lock();
l3.lock();
// pass l1,l2,l3 along to the threads running these methods, so they are available to the methods:
public void m1() {
try {
// do stuff
}
finally {
l1.unlock();
}
}
public void m2() {
l1.lock();
try {
// do stuff
}
finally {
l2.unlock();
}
}
public void m3() {
l2.lock();
try {
// do stuff
}
finally {
l3.unlock();
}
}
public void m4() {
l3.lock();
// do stuff
}
我的建议是,视我是否正确理解问题而定:
public void m4() {
m3();
do something;
}
public void m3() {
m2();
do something;
}
public void m2() {
m1();
do something;
}
public void m1() {
do something;
}
您不需要锁,但需要障碍:m(n+1)必须等到m(n)被调用。下面的代码假设只有一个序列或方法调用(m1/2/3是从不同的线程调用的,或者是在同一个线程上以正确的顺序调用的,否则您将永远等待闩锁)。如果可能发生多次,则需要重置(或者您可以使用移相器进行调整) 然而,这是一个有点奇怪的设计,因为您希望按顺序完成它,所以您应该只执行输出方法中的所有工作,该方法将等待所有输入都完成
private CountDownLatch inputLatch = new CountDownLatch(3);
private Object[] input = new Object[3];
public void setInput(int i, Object data) {
input[i] = data;
inputLatch.countDown(); // perhaps better check all input set
}
public Object processInput() {
inputLatch.await();
return process(input); // process in sequence
}
你只想让m1、m2、m3和m4按顺序执行,每个都在等待前一个?只要做:m1();m2();m3();m4();不过,我猜你希望发生一些稍微不同的事情。你能解释一下我上面写的东西为什么不能达到你想要的效果吗?我不知道为什么,但这让我想起了观察者模式…我不明白为什么,如果它们互相等待,就一个接一个地执行。方法不是从一个类中调用的,它们可以从不同的类中随机调用。那么为什么没有4个方法,其中m4()执行m3()第一;其中,m3()首先执行m2();m2()首先执行m1()的地方…这基本上不是一个信号量吗?是的,等待部分很好,但是如何在完成前一个方法后通知等待方法执行。不想执行定期检查。ps:如果您想要任意数量的方法,您可以始终使用ReentrantLock数组,并为每个方法传递两个锁。一个用于在开始时锁定,另一个用于在结束时解锁(考虑到它们可能为null且不执行任何操作)。
private CountDownLatch inputLatch = new CountDownLatch(3);
private Object[] input = new Object[3];
public void setInput(int i, Object data) {
input[i] = data;
inputLatch.countDown(); // perhaps better check all input set
}
public Object processInput() {
inputLatch.await();
return process(input); // process in sequence
}