ExecutorService介绍2

时间:2021-03-07 08:21:15

Thread和ExecutorService的区别

使用Thread,当子线程执行结束后,主线程如果没有其他执行任务,主线程会终止。

/**
* Created by litao on 15/10/7.
*/
public class ThreadTest { public static void main(String[] args)
{
Thread threadA=new Thread()
{
@Override
public void run() {
super.run();
System.out.println("This is a test");
}
};
threadA.start(); }
}

结果:

This is a test

Process finished with exit code 0

使用ExecutorService,当子线程执行结束后,主线程如果没有其他执行任务,主线程并不会退出,除非在主线程调用了ExecutorService.shutdown()或者ExecutorService.shutdownNow()

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* Created by litao on 15/10/8.
*/
public class ExecutorServiceTest { public static void main(String[] args)
{
ExecutorService service= Executors.newFixedThreadPool(3);
service.submit(new Runnable() {
public void run() {
System.out.println("sub thread");
}
}); System.out.println("main thread");
} }

结果:

sub thread

main thread

/* 程序并没有退出 */

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* Created by litao on 15/10/8.
*/
public class ExecutorServiceTest { public static void main(String[] args)
{
ExecutorService service= Executors.newFixedThreadPool(3);
service.submit(new Runnable() {
public void run() {
System.out.println("sub thread");
}
}); System.out.println("main thread");
service.shutdown();
} }

结果:

main thread

sub thread

Process finished with exit code 0

结论: 在使用ExecutorService处理多线程任务时,当任务执行完毕后,需要调用ExecutorService.shutdown()关闭线程池。

ExecutorService中几个提交任务的方法

execute(Runnable): 继承自executor接口,在线程池中执行一个单独的不需要返回值的任务。

<T> Future<T> submit(Callable<T> task): 在线程池中执行一个需要有返回值的任务。 通过Future.get()方法获取任务执行结果。

<T> Future<T> submit(Runnable task, T result): 在线程池中执行一个不需要有返回值的任务,当任务执行结束(不管任务是否被中断),Future.get()可以获得指定的result值。

Future<?> submit(Runnable task):在线程池中执行一个不需要有返回值的任务,当任务执行结束,,Future.get()返回null

<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException: 执行tasks集合中的任务,当所有的任务执行结束后,按照任务提交的顺序返回记录任务执行结果和状态的Future类型的list集合 。invokeAll会阻塞直到返回Future类型的list集合。

<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit) throws InterruptedException:

和上面的invokeAll作用相同,增加了阻塞超时的判断。当超时返回值后,线程池中没有执行结束的任务会被中断(cancel)。

<T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException:

执行tasks集合中的任务,当某一个任务执行结束后,返回该任务的返回值。

<T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException:

和上面的invokeAny作用相同,增加了阻塞超时的判断。当超时返回值后,线程池中没有执行结束的任务会被中断(cancel)。

主线程在调用submit()或excute()方法后,并不会造成自己的阻塞,但是调用invokeAll()和invokeAny()方法会造成自己的阻塞。

调用future.get()方法会阻塞调用的主线程。当future对应的线程已经被阻塞,方法返回InterruptedException