在Java8中,如何在超时后终止异步运行的线程及其含义
我正在运行一个无限循环,需要实现以下步骤:在Java8中,如何在超时后终止异步运行的线程及其含义,java,multithreading,asynchronous,java-8,Java,Multithreading,Asynchronous,Java 8,我正在运行一个无限循环,需要实现以下步骤: 检查executor服务中的可用线程(无限循环) 获取循环中的任务 在后台执行任务(非阻塞),如果需要3秒以上,则终止执行任务的线程 我已经研究了未来的get-API,它接受一个超时参数,但这不是阻塞的本质 while(any thread available in thread pool){ Task task = fetchTask(); // somehow execute this task in a non-blocking fashio
while(any thread available in thread pool){
Task task = fetchTask();
// somehow execute this task in a non-blocking fashion with a timeout.
}
有没有办法在超时后终止异步执行的线程?
线程执行是否会在超时后停止并释放资源?要实现此行为,您需要:
import java.util.Date;
import java.util.concurrent.Callable;
public class Task implements Callable<String> {
private String name;
private Long elapsedTimeInMillSeconds = 0L;
static int counter = 0;
public Task(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
@Override
public String call() throws Exception {
Long startTimeInNanoSeconds, endTimeInNanoSeconds;
startTimeInNanoSeconds = System.nanoTime();
System.out.println("Executing : " + name + ", Current Seconds : " + new Date().getSeconds());
counter++;
System.out.println("Counter = " + counter + " for thread number " + name);
// Check if our logic is working as expected for Task2 we are going to delay for
// 7 seconds
if (counter == 2)
Thread.sleep(7000);
endTimeInNanoSeconds = System.nanoTime();
elapsedTimeInMillSeconds = (endTimeInNanoSeconds - startTimeInNanoSeconds) / 10000;
System.out
.println("Thread [ name : " + name + ", elapsed time : " + this.elapsedTimeInMillSeconds + " Ms ] ");
return "" + this.elapsedTimeInMillSeconds;
}
public synchronized Long getExecutionTime() {
return elapsedTimeInMillSeconds;
}
}
import java.util.Date;
导入java.util.concurrent.Callable;
公共类任务实现了可调用{
私有字符串名称;
专用长延时时间单位秒=0升;
静态整数计数器=0;
公共任务(字符串名称){
this.name=名称;
}
公共字符串getName(){
返回此.name;
}
@凌驾
公共字符串调用()引发异常{
长起始时间为毫秒,结束时间为毫秒;
starttimennanoseconds=System.nanoTime();
System.out.println(“正在执行:“+name+”,当前秒数:“+new Date().getSeconds());
计数器++;
System.out.println(“Counter=“+Counter+”表示螺纹号“+name”);
//检查我们的逻辑是否按照预期为我们将延迟的Task2工作
//7秒
如果(计数器==2)
睡眠(7000);
endTimeInNanoSeconds=System.nanoTime();
elapsedTimeInMillSeconds=(endTimeInNanoSeconds-startTimeInNanoSeconds)/10000;
系统输出
.println(“线程[名称:“+name+”,运行时间:“+this.elapsedTimeInMillSeconds+“Ms]”);
返回“+”this.elapsedTimeInMillSeconds;
}
公共同步的长getExecutionTime(){
返回ElapsedTimeinMills;
}
}
在你的主课中,尝试以下方法:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class Main {
static final int poolSize = 3;
static int counter = 1;
static final ExecutorService executor = Executors.newFixedThreadPool(poolSize);
public static void main(String[] args) {
List<Callable<Task>> callableTasks = new ArrayList<>();
Callable t1 = new Task("Task1");
Callable t2 = new Task("Task2");
Callable t3 = new Task("Task3");
callableTasks.add(t1);
callableTasks.add(t2);
callableTasks.add(t3);
try {
List<Future<Task>> futures = executor.invokeAll(callableTasks, 3, TimeUnit.SECONDS);
futures.stream().forEach(Ft -> {
Ft.cancel(true);
Task task = null;
try {
task = Ft.get();
} catch (Exception e) {
throw new CancellationException("This Thread has been terminated ");
}
});
executor.shutdownNow();
} catch (Exception e) {
if (e instanceof CancellationException) {
System.out.println("Exception : " + e.getMessage());
}
}
}
}
import java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.Callable;
导入java.util.concurrent.CancellationException;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.Future;
导入java.util.concurrent.TimeUnit;
公共班机{
静态最终int池大小=3;
静态整数计数器=1;
静态最终ExecutorService executor=Executors.newFixedThreadPool(池大小);
公共静态void main(字符串[]args){
List callableTasks=new ArrayList();
可调用t1=新任务(“任务1”);
可调用t2=新任务(“任务2”);
可调用t3=新任务(“任务3”);
callableTasks.add(t1);
callableTasks.add(t2);
callableTasks.add(t3);
试一试{
List futures=executor.invokeAll(callableTasks,3,TimeUnit.SECONDS);
futures.stream().forEach(Ft->{
Ft.cancel(真);
Task=null;
试一试{
task=Ft.get();
}捕获(例外e){
抛出新的CancellationException(“此线程已终止”);
}
});
执行者。关机现在();
}捕获(例外e){
if(取消异常的实例){
System.out.println(“异常:+e.getMessage());
}
}
}
}
计数器==2将被终止的线程,这是我们延迟的原因如果您使用的是线程池(执行器服务),您可能不想终止线程,而是想取消任务。您可以通过使用带有超时的
future.get()
来实现这一点-如果需要异步等待,您可以从单独的线程或线程池调用它。Re,“…这样做的含义。”线程通过访问共享变量进行通信。如果要终止的线程必须临时将任何共享变量置于任何类型的不一致/无效/无意义状态以执行其工作(即,如果线程有任何原因必须锁定锁),则终止线程可能会使这些变量处于不一致/无效/无意义状态。另外,在一些编程系统中(我忘记了Java),它也可能使锁永久锁定question@stacky请在我上次更新后再次检查此代码,好吗