Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在java中实现在一个方法中等待另一个方法完成?_Java - Fatal编程技术网

如何在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
 }