java多线程设置超时时间

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

百度了很多答案之后大部分的解决办法都是利用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(){
				@Override
				public 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(){
				@Override
				public 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() {
				@Override
				public 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应该提供一个方法有个超时时间的参数,超过时间后线程自动结束。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值