注意:这是玩具代码而不是准备好。
我想安排MyTask
运行每个固定延迟(例如2秒)。当完成时,这项任务希望自己停止。MyTask
的代码为:
public class MyTask implements Runnable {
MainClass parent;
AtomicInteger integer = new AtomicInteger(0);
public MyTask(MainClass parent) {
this.parent = parent;
}
@Override
public void run() {
try {
int valueNow = integer.incrementAndGet();
System.out.println("Running with value: " + valueNow + " and going to do work");
Thread.sleep((long)(Math.random() * 10000)); // simulate some work
System.out.println("Running with value: " + valueNow + " and work over");
if(valueNow == 5) {
parent.stopTask();
}
} catch (Exception exception) {
System.out.println("Interrupted");
}
}
}
和MainClass
是安排它的一个:
public class MainClass {
private ScheduledExecutorService executorService;
private ScheduledFuture updateFuture;
public static void main(String[] args) {
new MainClass().startMyTask();
}
public void startMyTask() {
System.out.println("Starting MyTask to run every 2 seconds..............");
executorService = Executors.newScheduledThreadPool(2);
updateFuture = executorService.scheduleAtFixedRate(new MyTask(this), 1, 2, TimeUnit.SECONDS);
}
public void stopTask() {
System.out.println("Stopping MyTask to run further");
updateFuture.cancel(true);
}
}
这只是复制场景的玩具代码。此方法有什么问题我将对父母的引用传递给线程以便可以停止?有什么更好的方法?
好吧,'错误'是您在两个类之间创建一个环状依赖关系。它会起作用,但循环依赖性通常是不可取的。
,但很容易打破周期。您的任务不是通过父本身,而是可以接受Runnable
在完成后运行。基本上是一个回调。
public class MyTask implements Runnable {
Runnable runOnDone;
AtomicInteger integer = new AtomicInteger(0);
public MyTask(Runnable runOnDone) {
this.runOnDone = runOnDone;
}
@Override
public void run() {
try {
int valueNow = integer.incrementAndGet();
System.out.println("Running with value: " + valueNow + " and going to do work");
Thread.sleep((long)(Math.random() * 10000)); // simulate some work
System.out.println("Running with value: " + valueNow + " and work over");
if(valueNow == 5) {
runOnDone.run();
}
} catch (Exception exception) {
System.out.println("Interrupted");
}
}
}
然后可以像这样实例化任务: new MyTask(this::stopTask)
另外,您可以从任务中抛出异常,这也将结束重新安排。请参阅此stackoverflow答案。