每个线程应该运行 10 分钟,如果时间结束则中断线程

Posted

技术标签:

【中文标题】每个线程应该运行 10 分钟,如果时间结束则中断线程【英文标题】:Each thread should run for 10 minutes and then interrupt the thread if the time is over 【发布时间】:2013-02-25 02:41:44 【问题描述】:

我正在尝试创建一个ExecutorService 实现,可以为每个线程提供超时或中断。

在下面的示例中,假设我正在生成 2 threads(在实际场景中,这个数字会很高),那么我需要确保 each thread 应该为 10 minutes 运行。 这意味着,Thread1 will run for 10 minutesThread2 will run for 10 minutes as well。如果 10 分钟结束,那么我需要中断线程或超时。

以下是我到目前为止的代码,我无法理解如何以如此干净的方式在此处添加此 interrupt or timeout 功能,以便如果我在我的代码中使此 no of threads 参数可配置,那么它在那里也应该可以正常工作。

public static void main(String[] args) 

    final int noOfThreads = 2;
    final long exp_time_millis = 600000; //10 minutes

    //create thread pool with given size 
    ExecutorService service = Executors.newFixedThreadPool(noOfThreads);


    for (int i = 0, i< noOfThreads; i++) 
        service.submit(new ThreadTask());
    



class ThreadTask implements Runnable 

    @Override
    public void run() 

        while(true) 
            System.out.println("Thread running...");
            try 

        /* make a select sql to the database 
         * and measure how much time it is taking in 
         * returning the response
         */

             catch (InterruptedException e) 

            
        
    

任何建议都会有很大帮助。

我已经看过几篇关于 SO 的文章,但我找不到任何符合我的场景的东西,我可以轻松实现。

更新代码:-

我正在尝试下面的代码,但它在运行方法中的 catch 块上给了我错误。不确定我是否做错了什么。谁能帮帮我?

public class ThreadTimeout 

    public static void main(String[] args) 

        final int noOfThreads = 2;

        //create thread pool with given size 
        ExecutorService service = Executors.newFixedThreadPool(noOfThreads);

        ScheduledExecutorService scheduleService = Executors.newScheduledThreadPool(noOfThreads);
        for (int i = 0; i< noOfThreads; i++) 
            final Future future = service.submit(new ThreadTask());
            scheduleService.schedule(new Runnable()
                public void run()
                    future.cancel(true);
                
            , 10, TimeUnit.MINUTES);
        
    


class ThreadTask implements Runnable 

    @Override
    public void run() 

           //make a database connection

        while (true) 
            System.out.println("Thread running...");
            try 
                /*
                 * make a select sql to the database and measure
                 * how much time it is taking in returning the
                 * response
                 */
             catch (InterruptedException e) 

            
        
    

【问题讨论】:

【参考方案1】:

我建议使用第二个ScheduledExecutorService。您可以将原始提交返回的Future 提交给ScheduledExecutorService 以取消。

ScheduledExecutorService scheduleService =   Executors.newScheduledThreadPool(n);
for (int i = 0, i< noOfThreads; i++)  
   final Future future = service.submit(new ThreadTask());
   scheduleService.schedule(new Runnable()
       public void run()
           future.cancel(true);
       
  , 10, TimeUnits.MINUTES);

现在ThreadTask 需要响应中断,否则这将无济于事。

【讨论】:

感谢约翰的帮助。我已经用你的代码和我的代码中的 sn-p 更新了我的问题。但是我在 catch 块中遇到错误,要求我删除异常。但我想你曾向我提到ThreadTask 需要回复interruption。对?我知道,我可以添加Thread.sleep,但在实际代码中,我将对数据库执行select sql calls。你知道我该怎么做吗?或者,如果您可以通过结合您的代码和我的代码为我提供完整的流程,那对我也将有很大帮助。这样我可以更好地理解。 还有一件事,newScheduledThreadPool(n) 这里的 n 应该与 newFixedThreadPool(noOfThreads); 的线程数相同,对吧? 嗨,约翰,你能帮我解决我的问题吗?提前致谢。 And one more thing ,newScheduledThreadPool(n) 不一定。您可以摆脱 1 个或几个线程。他们所要做的就是向他们应该取消的其他线程发出信号。该线程通常不会做太多工作。 Do you know how can I do that? 取决于 SQL 驱动程序本身是否响应中断。你也可以看看这个问题***.com/questions/9492777/…。您可以改为将if(!Thread.currentThread().isInterrupted()) 作为条件。【参考方案2】:

我建议使用ExecutorService.awaitTermination(...); 方法,然后使用ExecutorService.shutdownNow() 方法。

例如:

for (int i = 0; i < noOfThreads; i++) 
    service.submit(new ThreadTask());

// we always need to shutdown the service _after_ we've submitted all jobs
service.shutdown();
// now we wait for those tasks to finish for 10 minutes
if (!service.awaitTermination(10, TimeUnit.MINUTES)) 
    // if we timed out waiting for the tasks to finish, forcefully interrupt them
    service.shutdownNow();

请注意,这将中断线程,但这只会导致某些方法,例如Thread.sleep()Object.wait(),以及其他一些方法抛出InterruptedException。它还在线程上设置中断位,可以使用Thread.currentThread().isInterrupted() 进行测试。它不会像你对 unix 进程一样“杀死”线程。

【讨论】:

以上是关于每个线程应该运行 10 分钟,如果时间结束则中断线程的主要内容,如果未能解决你的问题,请参考以下文章

如果未加入则中断线程

一般来说,主方法main()结束的时候线程结束

JAVA-初步认识-第十四章-多线程(守护线setDaemon)

一文搞懂 Java 线程中断

Java线程中断

线程中断以及线程中断引发的那些问题