Future对象在执行使用在外线程中还是同步执行
执行后的结果用时
[b]看到前面的调用使用了future并没有体现出他的优势,所以在使用时候调用还是同步,我改进一下调用优化[/b]
改进后执行后的用时
如果在调用时候发生异常情况会怎么样,上边的如果有异常发生会出现消息不能正常处理。看看结果
抛出异常后的执行结果可以看到只要前面有异常就会阻碍后边的程序执行
继续优化异常捕获
看看执行后的日志记录
可以看见执行成功执行的会正常执行完成,想象一下这里我们可以自己处理这些异常,比如将没有执行成功的数据放入消息队列或者放入数据库都可以,等待下次处理或找到调用的问题。
[b]最后版本[/b]
现在我们看看最后的执行效果,看着就很舒服了
实际使用中可能会有不同的callable调用,你可以实现自己的callable。
public class CallableFutureTest {
ExecutorService executor = Executors.newFixedThreadPool(3);
@Test
//@Ignore
public void testCallable() {
long start=System.currentTimeMillis();
try {
for (int i = 0; i < 5; i++) {
Callable c = new Callable() {
public Object call() throws Exception {
Boolean random = new Random().nextBoolean();
System.out.println(Thread.currentThread().getName() + "任务启动" + random);
Thread.sleep(3000);
return random;
}
};
Future<Boolean> f = executor.submit(c);
if (!f.get()) {
System.out.println("执行continue操作" + f.get());
continue;
}
System.out.println("执行后插入数据");
}
System.out.println("执行时间最后用时-------------------------"+(System.currentTimeMillis()-start));
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
executor.shutdown();
}
}
执行后的结果用时
Connected to the target VM, address: '127.0.0.1:50960', transport: 'socket'
pool-1-thread-1任务启动true
执行后插入数据
pool-1-thread-2任务启动false
执行continue操作false
pool-1-thread-3任务启动true
执行后插入数据
pool-1-thread-1任务启动false
执行continue操作false
pool-1-thread-2任务启动false
执行continue操作false
执行时间最后用时-------------------------14979
[b]看到前面的调用使用了future并没有体现出他的优势,所以在使用时候调用还是同步,我改进一下调用优化[/b]
public class CallableFutureTest {
ExecutorService executor = Executors.newFixedThreadPool(3);
@Test
public void testCallable() {
long start=System.currentTimeMillis();
//创建多个线程的返回值
List<Future> list = Lists.newArrayList();
try {
for (int i = 0; i < 5; i++) {
Callable c = new Callable() {
public Object call() throws Exception {
Boolean random = new Random().nextBoolean();
System.out.println(Thread.currentThread().getName() + "任务启动" + random);
Thread.sleep(3000);
return random;
}
};
Future<Boolean> f = executor.submit(c);
list.add(f);
}
for (Future<Boolean> future : list) {
if (!future.get()) {
System.out.println("执行continue操作" + future.get());
continue;
}
System.out.println("执行后插入数据");
}
System.out.println("执行时间最后用时-------------------------"+(System.currentTimeMillis()-start));
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
executor.shutdown();
}
}
改进后执行后的用时
Connected to the target VM, address: '127.0.0.1:52304', transport: 'socket'
pool-1-thread-1任务启动true
pool-1-thread-2任务启动true
pool-1-thread-3任务启动true
pool-1-thread-3任务启动true
执行后插入数据
执行后插入数据
执行后插入数据
pool-1-thread-2任务启动false
Disconnected from the target VM, address: '127.0.0.1:52304', transport: 'socket'
执行后插入数据
执行continue操作false
执行时间最后用时-------------------------6018
如果在调用时候发生异常情况会怎么样,上边的如果有异常发生会出现消息不能正常处理。看看结果
@Test
public void testCallable() {
long start = System.currentTimeMillis();
//创建多个线程的返回值
List<Future> list = Lists.newArrayList();
for (int i = 0; i < 5; i++) {
Callable c = new Callable() {
public Object call() throws Exception {
Boolean random = new Random().nextBoolean();
System.out.println(Thread.currentThread().getName() + "任务启动" + random);
Thread.sleep(2000);
if (!random) {
throw new InterruptedException("执行线程被打断异常");
}
return random;
}
};
Future<Boolean> f = executor.submit(c);
list.add(f);
}
try {
for (Future<Boolean> future : list) {
if (!future.get()) {
System.out.println("执行continue操作" + future.get());
continue;
}
System.out.println("执行后插入数据");
} } catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("执行时间最后用时-------------------------" + (System.currentTimeMillis() - start));
executor.shutdown();
}
抛出异常后的执行结果可以看到只要前面有异常就会阻碍后边的程序执行
pool-1-thread-1任务启动false
pool-1-thread-2任务启动false
pool-1-thread-3任务启动false
pool-1-thread-2任务启动false
pool-1-thread-3任务启动true
执行时间最后用时-------------------------2015
java.util.concurrent.ExecutionException: java.lang.InterruptedException: 执行线程被打断异常
Caused by: java.lang.InterruptedException: 执行线程被打断异常
继续优化异常捕获
@Test
public void testCallable() {
long start = System.currentTimeMillis();
//创建多个线程的返回值
List<Future> list = Lists.newArrayList();
for (int i = 0; i < 5; i++) {
Callable c = new Callable() {
public Object call() throws Exception {
Boolean random = new Random().nextBoolean();
System.out.println(Thread.currentThread().getName() + "任务启动" + random);
Thread.sleep(2000);
if (!random) {
throw new InterruptedException("执行线程被打断异常");
}
return random;
}
};
Future<Boolean> f = executor.submit(c);
list.add(f);
}
for (Future<Boolean> future : list) {
try {
if (!future.get()) {
System.out.println("执行continue操作" + future.get());
continue;
}
System.out.println("执行后插入数据");
} catch (InterruptedException e) {
System.out.println("-----------------------------执行中途有异常出现InterruptedException");
e.printStackTrace();
} catch (ExecutionException e) {
System.out.println("-----------------------------执行中途有异常出现ExecutionException");
e.printStackTrace();
}
}
System.out.println("执行时间最后用时-------------------------" + (System.currentTimeMillis() - start));
executor.shutdown();
}
看看执行后的日志记录
pool-1-thread-1任务启动false
pool-1-thread-2任务启动true
pool-1-thread-3任务启动true
pool-1-thread-3任务启动true
pool-1-thread-2任务启动false
-----------------------------执行中途有异常出现ExecutionException
执行后插入数据
执行后插入数据
java.util.concurrent.ExecutionException: java.lang.InterruptedException: 执行线程被打断异常
Caused by: java.lang.InterruptedException: 执行线程被打断异常
执行后插入数据
java.util.concurrent.ExecutionException: java.lang.InterruptedException: 执行线程被打断异常
Caused by: java.lang.InterruptedException: 执行线程被打断异常
Disconnected from the target VM, address: '127.0.0.1:55843', transport: 'socket'
-----------------------------执行中途有异常出现ExecutionException
执行时间最后用时-------------------------4028
可以看见执行成功执行的会正常执行完成,想象一下这里我们可以自己处理这些异常,比如将没有执行成功的数据放入消息队列或者放入数据库都可以,等待下次处理或找到调用的问题。
[b]最后版本[/b]
@Test
public void testCallable() {
long start = System.currentTimeMillis();
//创建多个线程的返回值
List<Future> list = Lists.newArrayList();
for (int i = 0; i < 5; i++) {
Callable c = new Callable() {
public Object call() throws Exception {
Boolean random = new Random().nextBoolean();
System.out.println(Thread.currentThread().getName() + "任务启动" + random);
Thread.sleep(2000);
if (!random) {
throw new InterruptedException("执行线程被打断异常");
}
return random;
}
};
Future<Boolean> f = executor.submit(c);
list.add(f);
}
for (Future<Boolean> future : list) {
try {
if (!future.get()) {
System.out.println("执行continue操作" + future.get());
continue;
}
System.out.println("执行后插入数据成功");
} catch (InterruptedException e) {
System.out.println("将异常数据记录到mq或数据库或做补充异步操作-----------------------------执行中途有异常出现InterruptedException");
continue;
} catch (ExecutionException e) {
System.out.println("将异常数据记录到mq或数据库或做补充异步操作-----------------------------执行中途有异常出现ExecutionException");
continue;
}
}
System.out.println("执行时间最后用时-------------------------" + (System.currentTimeMillis() - start));
executor.shutdown();//记住这里在使用完后一定要关闭避免引起资源的浪费和死锁
}
现在我们看看最后的执行效果,看着就很舒服了
Connected to the target VM, address: '127.0.0.1:56951', transport: 'socket'
pool-1-thread-1任务启动true
pool-1-thread-3任务启动false
pool-1-thread-2任务启动false
执行后插入数据
pool-1-thread-1任务启动false
pool-1-thread-3任务启动true
将异常数据记录到mq或数据库或做补充异步操作-----------------------------执行中途有异常出现ExecutionException
将异常数据记录到mq或数据库或做补充异步操作-----------------------------执行中途有异常出现ExecutionException
Disconnected from the target VM, address: '127.0.0.1:56951', transport: 'socket'
将异常数据记录到mq或数据库或做补充异步操作-----------------------------执行中途有异常出现ExecutionException
执行后插入数据
执行时间最后用时-------------------------4013
实际使用中可能会有不同的callable调用,你可以实现自己的callable。