对于多线程大家都不陌生,可以提高咱们程序的执行效率,但是各线程之间都是独立运行,如何来获取各个线程的数据并集中处理呢?废话少说,下面上代码。
1.首先多线程要实现Callable接口,记住是Callable,一定要加上object泛型:
public class ReportThread implements Callable<Object> {
private Integer num;//线程标记
private CountDownLatch count;//线程计数器
public ReportThread(Integer num,CountDownLatch count){
this.num = num;
this.count = count;
}
public Object call() {
String msg = "";
try {
msg = "我是线程"+num;
} catch (Exception e) {
e.printStackTrace();
}finally {
count.countDown();
return msg;
}
}
}
2.然后在主程序中,调用该线程时使用future获取返回值:
public static void execute() {
//线程池堵塞队列
ArrayBlockingQueue<Runnable> workQueue=null;
//线程池队列
ThreadPoolExecutor pool=null;
//线程计数器
CountDownLatch end = null;
try {
//开启线程池
workQueue=new ArrayBlockingQueue<Runnable>(5);
pool=new ThreadPoolExecutor(10, 20, 200,
TimeUnit.MILLISECONDS, workQueue);
//创建线程
Callable rt = new ReportThread(1,end);
//执行线程任务并获取返回值
Future f = pool.submit(rt);
//将返回的futrue进行类型转换
String msg = f.get().toString();
System.out.println(msg);
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if(pool != null){
pool.shutdown();//关闭线程池
}
}catch (Exception e1){
e1.printStackTrace();
}
}
}
最终运行结果:
我是线程1
是不是非常简单呢?但是这种获取多线程返回值的方式有很大的缺点,那就是会导致线程阻塞,主线程必须等待该线程获取到返回值后才执行下一个,感觉已经失去了多线程的意义,效率会大大降低,所以大家一定结合自身实际的应用场景来使用。
那么就有人问了,如果我既想用多线程又要获取返回值,还不能让线程阻塞呢?就没有办法了吗?当然是有的,那就是用引用传递(不知道引用传递的小伙伴自行百度补一补基础知识哈)。还是以上面为例:
public class ReportThread extends Thread {
private Integer num;//线程标记
private CountDownLatch count;//线程计数器
private List<String> list;
public ReportThread(Integer num,CountDownLatch count,
List<String> list){
this.num = num;
this.count = count;
this.list = list;
}
public void run() {
String msg = "";
try {
msg = "我是线程"+num;
list.add(msg);
} catch (Exception e) {
e.printStackTrace();
}finally {
count.countDown();
}
}
}
public static void execute() {
//线程池堵塞队列
ArrayBlockingQueue<Runnable> workQueue=null;
//线程池队列
ThreadPoolExecutor pool=null;
//线程计数器
CountDownLatch end = null;
List<String> reList = null;
try {
//开启线程池
workQueue=new ArrayBlockingQueue<Runnable>(5);
pool=new ThreadPoolExecutor(0, 20, 200,
TimeUnit.MILLISECONDS, workQueue);
//创建线程计数器
end = new CountDownLatch(3);
reList = new ArrayList<ReportEntity>();
for(int i=1;i<=3;i++){
//创建线程
Thread rt = new ReportThread(i,end,reList);
//执行线程任务
pool.execute(rt);
}
//当所有线程执行完毕后才继续执行后续代码
end.await();
//
for(String str:reList){
System.out.println(str);
}
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if(pool != null){
pool.shutdown();//关闭线程池
}
}catch (Exception e1){
e1.printStackTrace();
}
}
}
最终运行结果:
我是线程1
我是线程2
我是线程3
可以看到没有用future接收返回值,依然将各子线程中的msg打印出来了,是不是很巧妙呢?其实还有一些别的方式可以获取,欢迎大家来补充!一起交流进步!