static class MyThread0 extends Thread{
其中继承Thread和实现的接口Runnable的run没有返回值,如果我们想要拿到一个Thread的执行结果就要实现 Callable接口。
二、现在使用多线程通常不会直接用Thread对象了,而是使用java.util.concurrent包下的Executor或者ExecutorService类来初始化一个线程池供我们使用。
Executors类,提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口。
1、public static ExecutorService newFixedThreadPool(int nThreads)
创建固定数目线程的线程池。
2、public static ExecutorService newCachedThreadPool()
创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。
3、public static ExecutorService newSingleThreadExecutor()
创建一个单线程化的Executor。
4、public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。
三、下面说一下ExecutorService的一些简单用法:
比如下面的一个小例子:
例1:初始化线程池。
public static void main(String[] args) {
Executor executor = Executors.newFixedThreadPool(10);
Runnable task = new Runnable() {
public void run() {
System.out.println("task over");
}
};
executor.execute(task);
}
例2: ExecutorService 可以通过submit(***)传递一个Callable,或Runnable,返回Future,所以我们可以将多个线程的get()方法拿到的执行结果Future,将结果放在一个集合中进行计算。但是submit返回的结果Future的get()方法是阻塞的,如果任务还没有完成则当前线程会阻塞,这个要注意。
@Test
public void test() throws InterruptedException, ExecutionException{
Future<?> _future = null;
ExecutorService exec = Executors.newFixedThreadPool(5);// 初始化一个线程池
//CountDownLatch countDownLatch = new CountDownLatch(10);
System.out.println("--------- create thread... --------");
try {
// 开启线程
_future = exec.submit(new OneThread());//ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。
//countDownLatch.await();
} catch (Exception e) {
System.out.println("---------createSoFromBzOrderQueueWithMultithread TASK thread: "+Thread.currentThread().getName() + ":Interrupted--------");
} finally {
exec.shutdown();
System.out.println("--------- ExecutorService shutdown --------");
}
doSomeThing();// 在exec.submit(new OneThread());之后和_future.get()之前我们可以继续做其他事情
System.out.println("future.get() = "+_future.get()); //在_future.get()处如果任务还没有完成则当前线程会阻塞,直到线程完成返回结果
System.out.println("Hello, World!");
}
static class OneThread implements Callable<String> {
public String call() throws Exception {
String ret = " i test callable";
for (int i = 0; i < 20; i++) {
try {
Thread.sleep(1 * 1000L);
System.out.println("OneThread "+i+" sleep 1s");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return ret; // 实现Callable接口返回结果
}
}
例2的主要问题在于如果Executor后台线程池还没有完成Callable的计算,调用返回Future对象的get()方法时当前线程会阻塞直到计算完成。
如果我们希望任意子任务在完成后就把其结果加到我们的集合中,而不用依次等待每个任务完成,可以使CompletionService ,CompletionService整合了Executor和BlockingQueue的功能。