java多线程设置超时时间

来源:互联网 发布:linux7安装mysql 编辑:程序博客网 时间:2024/04/30 14:11

情景:多线程中个别线程执行时间会很长,如果线程执行时间超过某段时间,自动结束该线程

百度了很多答案之后大部分的解决办法都是利用Future类中的get(long timeout,TimeUnit unit) 方法进行设置,但是这个方法是阻塞的,在取不到结果之前是不会执行后边的程序的。

下面代码是按照这个方法进行的测试:

public static void main(String[] args) {ExecutorService pool = Executors.newFixedThreadPool(40);//创建一个可容纳40个线程的线程池for(int i=0;i<40;i++){System.out.println(i+"开始时间:"+System.currentTimeMillis());Future future = pool.submit(new Runnable(){@Overridepublic void run() {try {Thread.currentThread().sleep(300);} catch (InterruptedException e) {}System.out.println("结束时间:"+System.currentTimeMillis());}});try {future.get(200, TimeUnit.MILLISECONDS);} catch (InterruptedException e) {future.cancel(true);} catch (ExecutionException e) {future.cancel(true);} catch (TimeoutException e) {future.cancel(true);}}}
预期结果:0到40都开始执行了之后,然后对线程进行超时判断

执行结果:0开始时间:1487675573448
结束时间:1487675573651
1开始时间:1487675573651
2开始时间:1487675573851
结束时间:1487675573851
3开始时间:1487675574052
结束时间:1487675574052
4开始时间:1487675574253
结束时间:1487675574253
。。。

会发现只有0结束后1才会开始,跟预期的结果不一致,完全没有起到多线程该有的作用!


解决方案:

究其根源其实是在get方法,get方法会一直等待线程完成后才会继续,解决思路就是:

让40个线程开始执行,然后再开40个线程分别进行get。

public static void main(String[] args) {ExecutorService pool = Executors.newFixedThreadPool(40);//创建一个可容纳40个线程的线程池final List<Future> threadList = new ArrayList<Future>();for(int i=0;i<40;i++){System.out.println(i+"开始时间:"+System.currentTimeMillis());Future future = pool.submit(new Runnable(){@Overridepublic void run() {try {Thread.currentThread().sleep(300);} catch (InterruptedException e) {}System.out.println("结束时间:"+System.currentTimeMillis());}});threadList.add(future);}for(Future future:threadList){final Future futureTemp = future;Thread t = new Thread(new Runnable() {@Overridepublic void run() {try {futureTemp.get(200, TimeUnit.MILLISECONDS);} catch (InterruptedException e) {futureTemp.cancel(true);} catch (ExecutionException e) {futureTemp.cancel(true);} catch (TimeoutException e) {futureTemp.cancel(true);}}});t.start();}}


结果:

0开始时间:1487676230783
1开始时间:1487676230784
2开始时间:1487676230785
3开始时间:1487676230785
4开始时间:1487676230785
5开始时间:1487676230785
6开始时间:1487676230785
。。。
结束时间:1487676230993
结束时间:1487676230993
结束时间:1487676230993
结束时间:1487676230994
结束时间:1487676230994
结束时间:1487676230994
结束时间:1487676230994
。。。

完美解决。


总结:还是觉得jdk应该提供一个方法有个超时时间的参数,超过时间后线程自动结束。

0 0