多线程任务Callable与Future或FutureTask的使用
2016-07-15 10:36
585 查看
在进行多线程任务时,我们可以使用Thread、Runnable已经java5以后新增的concurrent包内的Callable,Runable跟Thread的用法就不说了,这里要说的是使用Runnable时,如何获取结果以及抛出的异常,这样子很难定位在执行多线程任务时的程序异常。这里推荐使用Callable和Future或者FutureTask配合,获取结果。
简单的使用代码
//Callable实现类
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
/**
*
* @author PYY
*
*/
public class CounterThread implements Callable<Integer> {
private CountDownLatch countDownSign;
private String name;
public CountDownLatch getCountDownSign() {
return countDownSign;
}
public void setCountDownSign(CountDownLatch countDownSign) {
this.countDownSign = countDownSign;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public CounterThread(String name) {
this.name = name;
}
@Override
public Integer call() throws Exception {
int result = 0;
try {
System.out.println(name + "正在执行中,准备运算");
result = 3 / (int) (Math.random() * 3);
} catch(Exception e) {
System.out.println(name + "执行异常");
} finally {
countDownSign.countDown();
}
return result;
}
}
1 使用future接口获取
<pre name="code" class="java">ExecutorService service = Executors.newSingleThreadExecutor();
CounterThread counter = new CounterThread("线程" + i);
Future<?> future = service.submit(counter);
service.shutdown();
try {
//睡眠,等待子线程执行完成
Thread.sleep(1000);
} catch (InterruptedException e) {}
System.out.println("查看运行结果:" + future.get());
2 使用FutureTask类
ExecutorService service = Executors.newSingleThreadExecutor();
CounterThread counter = new CounterThread("线程" + i);
FutureTask<Integer> task = new FutureTask<Integer>()
service.submit(task);
service.shutdown();
try {
//睡眠,等待子线程执行完成
Thread.sleep(1000);
} catch (InterruptedException e) {}
System.out.println("查看运行结果:" + task.get());
但是在使用多线程时,不可能只使用一个线程,有时我们希望在所有的线程都进行完成后再统一获取结果,这时我们需要一个线程计数器,这里推荐CountDownLatch,不废话,直接上代码
List<Future<?>> taskList = new ArrayList<Future<?>>();
CountDownLatch latch = new CountDownLatch(30);
try {
for(int i = 0; i < 30; i++) {
ExecutorService service = Executors.newSingleThreadExecutor();
CounterThread counter = new CounterThread("线程" + i);
counter.setCountDownSign(latch);
Future<?> future = service.submit(counter);
taskList.add(future);
service.shutdown();
}
//等待线程执行完成,计数器减到0
latch.await();
System.out.println("主线程执行完毕,查询子线程结果");
for(Future<?> task : taskList) {
System.out.println("查看" + task.isDone() + "运行结果:" + task.get());
}
} catch (Exception e) {
System.out.println("异常了");
e.printStackTrace();
}
更多学习 Callable、Future和FutureTask的内容,参考这篇博文
CountDownLatch文章移步这里
简单的使用代码
//Callable实现类
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
/**
*
* @author PYY
*
*/
public class CounterThread implements Callable<Integer> {
private CountDownLatch countDownSign;
private String name;
public CountDownLatch getCountDownSign() {
return countDownSign;
}
public void setCountDownSign(CountDownLatch countDownSign) {
this.countDownSign = countDownSign;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public CounterThread(String name) {
this.name = name;
}
@Override
public Integer call() throws Exception {
int result = 0;
try {
System.out.println(name + "正在执行中,准备运算");
result = 3 / (int) (Math.random() * 3);
} catch(Exception e) {
System.out.println(name + "执行异常");
} finally {
countDownSign.countDown();
}
return result;
}
}
1 使用future接口获取
<pre name="code" class="java">ExecutorService service = Executors.newSingleThreadExecutor();
CounterThread counter = new CounterThread("线程" + i);
Future<?> future = service.submit(counter);
service.shutdown();
try {
//睡眠,等待子线程执行完成
Thread.sleep(1000);
} catch (InterruptedException e) {}
System.out.println("查看运行结果:" + future.get());
2 使用FutureTask类
ExecutorService service = Executors.newSingleThreadExecutor();
CounterThread counter = new CounterThread("线程" + i);
FutureTask<Integer> task = new FutureTask<Integer>()
service.submit(task);
service.shutdown();
try {
//睡眠,等待子线程执行完成
Thread.sleep(1000);
} catch (InterruptedException e) {}
System.out.println("查看运行结果:" + task.get());
但是在使用多线程时,不可能只使用一个线程,有时我们希望在所有的线程都进行完成后再统一获取结果,这时我们需要一个线程计数器,这里推荐CountDownLatch,不废话,直接上代码
List<Future<?>> taskList = new ArrayList<Future<?>>();
CountDownLatch latch = new CountDownLatch(30);
try {
for(int i = 0; i < 30; i++) {
ExecutorService service = Executors.newSingleThreadExecutor();
CounterThread counter = new CounterThread("线程" + i);
counter.setCountDownSign(latch);
Future<?> future = service.submit(counter);
taskList.add(future);
service.shutdown();
}
//等待线程执行完成,计数器减到0
latch.await();
System.out.println("主线程执行完毕,查询子线程结果");
for(Future<?> task : taskList) {
System.out.println("查看" + task.isDone() + "运行结果:" + task.get());
}
} catch (Exception e) {
System.out.println("异常了");
e.printStackTrace();
}
更多学习 Callable、Future和FutureTask的内容,参考这篇博文
CountDownLatch文章移步这里
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- Python3写爬虫(四)多线程实现数据爬取
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序