我想在我的应用程序中创建两个线程,它们将运行两个方法。我使用的是构建器设计模式,在构建方法中,我有类似这样的内容,请求是传递的对象:
Rules rule;
Request build() {
Request request = new Request(this);
//I want one threat to call this method
Boolean isExceeding = this.rule.volumeExceeding(request);
//Another thread to call this method
Boolean isRepeating = this.rule.volumeRepeating(request);
//Some sort of timer that will wait until both values are received,
//If one value takes too long to be received kill the thread and continue with
//whatever value was received.
..Logic based on 2 booleans..
return request;
}
这是这个类的样子:
public class Rules {
public Boolean volumeExceeding(Request request) {
...some...logic...
return true/false;
}
public Boolean volumeRepeating(Request request) {
...some...logic...
return true/false;
}
}
我已在代码中注释了我想发生的事情。基本上,我想创建两个线程来运行各自的方法。它会等到两者都完成后,但是,如果一个过程花费的时间太长(例如:超过10ms),则返回已完成的值。我该如何创建?我试图理解多线程教程,但是这些示例是如此的通用,以至于很难理解它们所做的事情并将其应用于更复杂的事情。
答案 0 :(得分:2)
一种方法是使用CompletableFuture
s:
import java.util.concurrent.CompletableFuture;
class Main {
private static final long timeout = 1_000; // 1 second
static Boolean volumeExceeding(Object request) {
System.out.println(Thread.currentThread().getName());
final long startpoint = System.currentTimeMillis();
// do stuff with request but we do dummy stuff
for (int i = 0; i < 1_000_000; i++) {
if (System.currentTimeMillis() - startpoint > timeout) {
return false;
}
Math.log(Math.sqrt(i));
}
return true;
}
static Boolean volumeRepeating(Object request) {
System.out.println(Thread.currentThread().getName());
final long startpoint = System.currentTimeMillis();
// do stuff with request but we do dummy stuff
for (int i = 0; i < 1_000_000_000; i++) {
if (System.currentTimeMillis() - startpoint > timeout) {
return false;
}
Math.log(Math.sqrt(i));
}
return true;
}
public static void main(String[] args) {
final Object request = new Object();
CompletableFuture<Boolean> isExceedingFuture = CompletableFuture.supplyAsync(
() -> Main.volumeExceeding(request));
CompletableFuture<Boolean> isRepeatingFuture = CompletableFuture.supplyAsync(
() -> Main.volumeRepeating(request));
Boolean isExceeding = isExceedingFuture.join();
Boolean isRepeating = isRepeatingFuture.join();
System.out.println(isExceeding);
System.out.println(isRepeating);
}
}
请注意,一项任务要比另一项花费更长的时间。
发生了什么事?您通过使用CompletableFuture
执行将这些任务提供给公共池。两项任务均由两个不同的线程执行。您所要求的是,任务花费的时间太长就会停止。因此,您可以简单地记住任务开始的时间,并定期检查是否超时。 重要:进行此检查,以确保在数据保持一致状态时任务将返回。另外请注意,您当然可以进行多次检查。
关于CompletableFuture
:Guide To CompletableFuture
答案 1 :(得分:0)
如果我正确理解了您的问题,那么您应该使用票务系统(也称为提供者-消费者模式或生产者-消费者模式)来执行此操作,以便您的线程被重用(这是一个如果这些操作是时间紧迫的,则可以显着提高性能。
总体思路应该是:
应用初始化
运行时
n
毫秒,因为对于超时的等待时间,调度程序通常更“宽松”。例如Thread.sleep()
几乎总是相差一毫秒(据我所知,总是迟到,永远不会早到)。请记住,从外部停止或停止线程总是存在锁问题,因此,我建议您的作业会定期访问可能的退出点,因此,如果您不再关心结果,则可以安全地终止它们。< / p>