at java.lang.Thread.run(Thread.java:619)
说明:3秒之内没有执行完所以抛了TimeoutException异常,并取消了线程,可以看到后面就没有输出3,4了。注意这里call()函数中,
try catch在for循环之外
,这样执行结果是没有问题的,是我们想要的结果;但是,如果把try catch写在了for循环之内,结果会怎样呢,请看下例。另外,result值即为call()函数返回的值本例中为“call result”。
例子2:try catch在for循环之内
-
package
testexception;
-
-
import
java.util.concurrent.Callable;
-
import
java.util.concurrent.ExecutionException;
-
import
java.util.concurrent.ExecutorService;
-
import
java.util.concurrent.Executors;
-
import
java.util.concurrent.FutureTask;
-
import
java.util.concurrent.TimeUnit;
-
import
java.util.concurrent.TimeoutException;
-
-
-
public
class
FutureTaskTest{
-
public
static
void
main(String[] args) {
-
ExecutorService executor = Executors.newSingleThreadExecutor();
-
FutureTask<String> futureTask =
-
new
FutureTask<String>(
new
Callable<String>() {
-
public
String call() {
-
for
(
int
i =
0
; i <
5
; i++) {
-
try
{
-
Thread.sleep(
1000
);
-
System.out.println(
"------------------------"
+i);
-
}
catch
(InterruptedException e) {
-
System.out.println(
"InterruptedException1111111"
);
-
e.printStackTrace();
-
}
-
}
-
-
return
"call result"
;
-
}});
-
executor.execute(futureTask);
-
-
try
{
-
String result = futureTask.get(
3000
, TimeUnit.MILLISECONDS);
-
-
System.out.println(
"___________"
+result+
"_______________"
);
-
}
catch
(InterruptedException e) {
-
System.out.println(
"InterruptedException222222"
);
-
futureTask.cancel(
true
);
-
}
catch
(ExecutionException e) {
-
System.out.println(
"InterruptedException333333333"
);
-
futureTask.cancel(
true
);
-
}
catch
(TimeoutException e) {
-
System.out.println(
"!!!!!!!!Time out!!!!!!!!!!"
);
-
futureTask.cancel(
true
);
-
}
finally
{
-
executor.shutdown();
-
}
-
}
-
}
输出结果:
------------------------0
------------------------1
------------------------2
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
!!!!!!!!Time out!!!!!!!!!!
InterruptedException1111111
at testexception.FutureTaskTest$1.call(FutureTaskTest.java:20)
at testexception.FutureTaskTest$1.call(FutureTaskTest.java:1)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
------------------------4
说明:根据输出结果可以看到
只有线程3被中断了,后面线程并没有按照我们希望的超时之后就停下来,即使我们在超时异常里面取消了线程
。也就是说,try catch在for循环之内时,取消线程后会让线程中断,所以第四次循环未执行完即被中断,抛出中断异常,然而这个中断异常被for循环之内的线程中断异常catch捕获到,所以
它仍会继续后面的循环输出
。但其实现在的线程已经被标识为中断了,如果你在超时异常catch块中输出futureTask.isCancelled(),你会发现返回的是true。使用时要特别注意这种容易出错的情况。
来源URL:http://blog.csdn.net/zlj526/article/details/40782027Callable接口和Future接口介绍 在Java中,如果需要设定代码执行的最长时间,即超时,可以用Java线程池ExecutorService类配合Future接口来实现。 Future接口是Java标准API的一部分,在java.util
原理是新建一个
Callable
线程
(call方法可以返回对象),用
Future
Task封装后,通过
future
对象的get方法来设定
超时
限制。如果
超时
,则
future
.cancel(true)取消执行。
重写
Callable
的call方法,在call方法中调用需要
超时
设置
的
接口
(在这里是listQuery())。
Callable
线程
我们放到
线程
池里执行。
import
java
.util.*;
import
java
.util.concurrent.*;
public class Main {
在
Java
中,如果需要设定代码执行的最
长
时间
,即
超时
,可以用
Java
线程
池ExecutorService类配合
Future
接口
来实现。
Future
接口
是
Java
标准API的一部分,在
java
.util.concurrent包中。
Future
接口
是
Java
线程
Future
模式的实现,可以来进行异步计算。
Future
模式可以这样来描述:我有一个任务,提交给了
Future
,Fu
前段
时间
在搞一个批量处理程序,涉及到
多线程
操作。但是后台服务很不给力,并发一大常常就挂了,
长
时间
不给返回,导致我的程序也挂死在那里……
那么能不能
设置
一段代码执行的
超时
时间
呢?如果处理
超时
就忽略该错误继续向下执行。
可是在网上搜了大半天,找到的都是无用的代码,根本不能用。
查了大量资料后发现,
java
早已经给我们提供了解决方案。jdk1.5自带的并发库中
Future
类就能满
线程
池
多线程
任务调用,串行阻塞式运行,虽然慢但稳妥要求单个
线程
运行时必须要有
超时
时间
,
超时
则放弃运行下一个任务这里的实现仅能用,不完善Main.
java
运行结果:
今天在项目开发中需要用到对执行方法加上
时间
控制
,如果方法执行过
长
则跳出执行,废话不说,直接上代码,用的是
线程
池配合
Callable
和
Future
方式对执行方法的
超时
阻断。希望各位牛人指正
//启用
线程
池
final ExecutorService exec = Executors.newFixedThreadPool(1);
Callable
>