java线程池——接收线程运行后返回的结果
java1.5新加入了线程同步的包。java.util.concurrent
其中有接口ExecutorService。
Executor提供了管理线程结束的方法,通过Future接口,能够跟踪一个或者多个异步线程运行的结果。
ExecutorService能够被shutdown,shutdown后,拒绝提交新的任务。ExecutorSerivce提供了两种shutdown的方式。shutdown()方法让先前已经提交的任务在终止操作前继续执行,而shutdownNow()方法阻止正在等待的线程启动,并且尝试终止当前正在运行的进程。终止线程后,Executor没有活跃的线程需要执行,也没有新的任务线程被提交。一个没有使用的ExecuteService应该被关闭,并且释放占用的资源。
Submit方法继承自Executor.execute(java.long.Runnable)方法,并且返回Future用来取消线程执行或者等待线程完成。invokeAny和invokeAll方法在执行大量线程时很常用。
Executors类提供了ExecutorService接口的工厂实现。
好,下面上货。
package com.xueyoucto.xueyou;
import java.util.concurrent.Callable;
public class ThreadReturnValue implements Callable {
@Override
public Object call() throws Exception {
int temp = 0;
StringBuffer sb = new StringBuffer("");
synchronized (App.GLOBALARRAY) {
for (int i = 0; i < App.GLOBALARRAY.length; i++) {
System.out.println(Thread.currentThread().getName() + "\n" + App.GLOBALARRAY[i]);
App.GLOBALARRAY[i] += 1;
temp += App.GLOBALARRAY[i];
sb.append("+").append(App.GLOBALARRAY[i]);
}
}
return sb.toString() + "=" + temp;
}
}
package com.xueyoucto.xueyou;
import java.util.concurrent.*;
/**
* Hello world!
*/
public class App {
public static int[] GLOBALARRAY = new int[50];
public static ThreadLocal<String[]> TLGLOBALARRAY = new ThreadLocal<String[]>() {
@Override
protected String[] initialValue() {
String[] temp = new String[50];
for (int i = 0; i < temp.length; i++) {
temp[i] = String.valueOf(i + 100);
}
return temp;
}
};
static {
for (int i = 0; i < GLOBALARRAY.length; i++) {
GLOBALARRAY[i] = i;
}
}
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(3);
Future<String> future = pool.submit(new ThreadReturnValue());
Future<String> future2 = pool.submit(new ThreadReturnValue());
Future<String> future3 = pool.submit(new ThreadReturnValue());
pool.shutdown(); // 不允许再想线程池中增加线程
//判断是否所有线程已经执行完毕
try {
boolean isFinish = pool.awaitTermination(1, TimeUnit.HOURS);
System.out.println(isFinish + "==========================");
//如果没有执行完
if (!isFinish) {
//线程池执行结束 不在等待线程执行完毕,直接执行下面的代码
pool.shutdownNow();
}
String r = future.get();
String r2 = future2.get();
String r3 = future3.get();
System.out.println(r);
System.out.println(r2);
System.out.println(r3);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//只给线程池中的线程1小时,然后就继续执行
System.out.println("it is ok !!!");
}
}
运行结果:
需要注意的是ExecutorService提供的是线程池的功能,并没有提供线程同步、互斥等功能,所以还是需要在互斥访问的变量上进行处理的。下面是没有处理的代码和结果,可以对比一下。
package com.xueyoucto.xueyou;
import java.util.concurrent.Callable;
public class ThreadReturnValue implements Callable {
@Override
public Object call() throws Exception {
int temp = 0;
StringBuffer sb = new StringBuffer("");
for (int i = 0; i < App.GLOBALARRAY.length; i++) {
System.out.println(Thread.currentThread().getName() + "\n" + App.GLOBALARRAY[i]);
App.GLOBALARRAY[i] += 1;
temp += App.GLOBALARRAY[i];
sb.append("+").append(App.GLOBALARRAY[i]);
}
return sb.toString() + "=" + temp;
}
}
运行结果(注意最后的结果):