ExecutorService

ExecutorService

2016-11-10  本文已影响1342人  米刀灵

接口 java.util.concurrent.ExecutorService 表述了异步执行的机制,并且可以让任务在后台执行。在下面的例子中可以发现线程被循环创建,但是启动线程却不是连续的,而是由ExecutorService决定的。
ExecutorService是一个接口,继承了Executor。而Executor亦是一个接口,该接口只包含了一个方法:void execute(Runnable command);,该方法接收一个 Runable 实例,它用来执行一个任务,任务即一个实现了 Runnable 接口的类。

创建ExecutorService:
Executors 提供了一系列工厂方法用于创先线程池,返回的线程池都实现了 ExecutorService 接口。

ExecutorService 使用方法:
这里有几种不同的方式让你将任务委托给壹個 ExecutorService。

执行 Runnable 任务:
通过 Executors 的以上四个静态工厂方法获得 ExecutorService 实例,而后调用该实例的 execute(Runnable command)方法即可。一旦 Runnable 任务传递到 execute()方法,该方法便会自动在一个线程上执行。下面是 Executor 执行 Runnable 任务的示例代码:

import java.util.concurrent.ExecutorService;   
import java.util.concurrent.Executors;   

public class TestCachedThreadPool{   
    public static void main(String[] args){   
        ExecutorService executorService = Executors.newCachedThreadPool();   
//      ExecutorService executorService = Executors.newFixedThreadPool(5);  
//      ExecutorService executorService = Executors.newSingleThreadExecutor();  
        for (int i = 0; i < 5; i++){   
            executorService.execute(new TestRunnable());   
            System.out.println("************* a" + i + " *************");   
        }   
        executorService.shutdown();   
    }   
}   

class TestRunnable implements Runnable{   
    public void run(){   
        System.out.println(Thread.currentThread().getName() + "线程被调用了。");   
    }   
}

执行结果如下:


从结果中可以看出,pool-1-thread-1 和 pool-1-thread-2 均被调用了两次,这是随机的,execute 会首先在线程池中选择一个已有空闲线程来执行任务,如果线程池中没有空闲线程,它便会创建一个新的线程来执行任务。

ExecuteService 服务的关闭:
当使用 ExecutorService 完毕之后,我们应该关闭它。 例如:你的程序通过 main() 方法启动,并且主线程退出了你的程序,如果你还有壹個活动的 ExecutorService 存在于你的程序中,那么程序将会继续保持运行状态。存在于 ExecutorService 中的活动线程会阻止Java虚拟机关闭。
为了关闭在 ExecutorService 中的线程,你需要调用 ***shutdown() 方法。executorService.shutdown();ExecutorService 并不会马上关闭,而是不再接收新的任务,壹但所有的线程结束执行当前任务,ExecutorServie 才会真的关闭。所有在调用 shutdown() 方法之前提交到 ExecutorService 的任务都会执行。
如果你希望立即关闭 ExecutorService,你可以调用
shutdownNow() ***方法。executorService.shutdownNow();这個方法会尝试马上关闭所有正在执行的任务,并且跳过所有已经提交但是还没有运行的任务。但是对于正在执行的任务,是否能够成功关闭它是无法保证的。
awaitTermination方法,方法调用会被阻塞,直到所有任务执行完毕并且shutdown请求被调用,或者参数中定义的timeout时间到达,或者当前线程被打断,这几种情况任意一个发生了就会导致该方法的执行。接收timeout和TimeUnit两个参数,用于设定超时时间及单位。当等待超过设定时间时,会监测ExecutorService是否已经关闭,若关闭则返回true,否则返回false。(若超时未关闭,程序也继续往下进行。传入Long.MAX_VALUE, TimeUnit.DAYS参数,可确保子进程完成。)一般情况下会和shutdown方法组合使用。

// 关闭启动线程 
service.shutdown(); 
// 等待子线程结束,再继续执行下面的代码 
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);  //这里表示近似永远等待
//service.awaitTermination(1, TimeUnit.MINUTES);//等待一分钟
//service.awaitTermination(2, TimeUnit.SECONDS);//两秒钟
System.out.println("all thread complete");

还有 service.isTerminated()service.isTerminating()service.isShutdown()等方法。


参考:
http://wiki.jikexueyuan.com/project/java-concurrency/executor.html
http://blog.csdn.net/bairrfhoinn/article/details/16848785
http://shift-alt-ctrl.iteye.com/blog/1841088

上一篇 下一篇

猜你喜欢

热点阅读