在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

我正在运行一个无限循环,需要实现以下步骤:

  • 检查executor服务中的可用线程(无限循环)
  • 获取循环中的任务
  • 在后台执行任务(非阻塞),如果需要3秒以上,则终止执行任务的线程 我已经研究了未来的get-API,它接受一个超时参数,但这不是阻塞的本质

    while(any thread available in thread pool){
    
    Task task = fetchTask();
    
    // somehow execute this task in a non-blocking fashion with a timeout.
    
    
    }
    
    有没有办法在超时后终止异步执行的线程?
    线程执行是否会在超时后停止并释放资源?

    要实现此行为,您需要:

  • 扩展Thread类并实现 可运行接口
  • 一个线程执行器,用于简单地异步执行线程
  • 让我们命名为“Task”的自定义类可以有如下特殊实现:

    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请在我上次更新后再次检查此代码,好吗