Java基本线程机制(二)
来源:互联网 发布:存储网络架构培训 编辑:程序博客网 时间:2024/05/21 16:25
三、Executor
Java SE 5以后,提供了Executor来管理Thread对象。Executor在客户端和任务执行之间提供了一个间接层,与Thread直接执行任务不同,这个中介对象将执行任务。有了Executor就不需要显示的管理线程的生命周期。
ExecutorService(具有服务周期的Executor)能够构建其阿丹的上下文来执行Runnable对象中的任务。
通常通过Executors的三个静态工厂方法来创建ExecutorService对象。
1、newCachedThreadPool();
/** * Creates a thread pool that creates new threads as needed, but * will reuse previously constructed threads when they are * available. These pools will typically improve the performance * of programs that execute many short-lived asynchronous tasks. * Calls to <tt>execute</tt> will reuse previously constructed * threads if available. If no existing thread is available, a new * thread will be created and added to the pool. Threads that have * not been used for sixty seconds are terminated and removed from * the cache. Thus, a pool that remains idle for long enough will * not consume any resources. Note that pools with similar * properties but different details (for example, timeout parameters) * may be created using {@link ThreadPoolExecutor} constructors. *
* 创建一个线程池,当需要新创建一个线程时,线程池就会创建新的线程。
* 如果先前创建的线程可用(空闲),则线程池会复用先前的线程,此时不需要
* 创建新的线程。这种线程池典型的适合于一个拥有许多的短生命周期线程的程序。
* 如果没有可用的线程,则线程池会创建一个新的线程并加入线程池,如果线程
* 空闲时间超过60秒,则该线程会被终止,并被移除线程池,释放资源。 * @return the newly created thread pool */ public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
此线程池只会在需要线程去执行任务时才会去创建或复用线程。
用Executor执行任务。public class CacheThreadPool {public static void main(String[] args) {ExecutorService exe = Executors.newCachedThreadPool();for(int i = 0; i < 5; i++){exe.execute(new LiftOff());}exe.shutdown();}}shutdown()方法:防止新任务提交给这个Executor,即这个Executor不接受新的任务,之后再执行Executor.execute(Runnable run)方法不能执行任务,但是,在shutdown之前提交的任务还是会执行,当所有任务的执行完毕时,程序将会尽快退出。
2、newFixedThreadPool()
/** * Creates a thread pool that reuses a fixed number of threads * operating off a shared unbounded queue. At any point, at most * <tt>nThreads</tt> threads will be active processing tasks. * If additional tasks are submitted when all threads are active, * they will wait in the queue until a thread is available. * If any thread terminates due to a failure during execution * prior to shutdown, a new one will take its place if needed to * execute subsequent tasks. The threads in the pool will exist * until it is explicitly {@link ExecutorService#shutdown shutdown}. *
* 创建包含有固定线程数(nThread)的线程池,并且维护一个共享的等待队列。
* 如果一个新加入的任务在提交时,所有的线程都是活动的,那么这个任务将被加入到
* 一个等待队列,直到有线程空闲为止。如果一个线程因为在执行时期因为错误而被关掉并终止,
* 此时,如果等待队列中还有未执行的任务,则线程池会创建一个新的线程来代替原来关闭的线程。
* 线程池里的线程会一直存在,除非被明确的关闭。
* @param nThreads the number of threads in the pool * @return the newly created thread pool * @throws IllegalArgumentException if {@code nThreads <= 0} */ public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
public class FixedThreadPool {public static void main(String[] args) {ExecutorService exe = Executors.newFixedThreadPool(5);for(int i = 0; i < 5; i++){exe.execute(new LiftOff());}exe.shutdown();}}
3、newSingleThreadPool()
/** * Creates an Executor that uses a single worker thread operating * off an unbounded queue. (Note however that if this single * thread terminates due to a failure during execution prior to * shutdown, a new one will take its place if needed to execute * subsequent tasks.) Tasks are guaranteed to execute 任务会被安全的已序列化的方式执行 * sequentially, and no more than one task will be active at any * given time. Unlike the otherwise equivalent * <tt>newFixedThreadPool(1)</tt> the returned executor is * guaranteed not to be reconfigurable to use additional threads. * * @return the newly created single-threaded Executor */ public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
此线程池就是线程数为1的FixedThreadPool.如果给这个SingleThreadPool提交了多个任务,则这些任务将按提交时间顺序排队,一个一个的执行。
一个任务执行,只有当他前面的任务执行完毕之后才能开始。即会序列化提交给他的任务,并维护自己的悬挂任务队列。
如果有多个任务需要处理同一个资源,且多个任务不能同时更改资源,可以用此线程池来处理,从而可以避免在共享资源上做同步处理。
public class SingleThreadExecutor {public static void main(String[] args) {ExecutorService exe = Executors.newSingleThreadExecutor();for(int i = 0; i < 5; i++){exe.execute(new LiftOff());}exe.shutdown();System.out.println("I LOVE YOU");}}
从源码中可以看出,其实这三个方法返回的都是同一类对象,只是这三个方法在创建这类对象时的初始化参数不一样而已。
创建对象的方法为::
new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }这个构造器里的
第一个参数是:构造的线程池中的核心线程数,所谓的核心线程可以简单的理解为线程池中最少需要拥有的线程。
第二个参数是:构造的线程池中最大的线程数。即该线程池最多拥有的线程数,如果线程池中已拥有的线程数等于这个最大值,并且所有线程都是活动的,此时如果提交给该线程池任务,则该任务会被挂起,加入到悬挂任务队列。
第三个参数是:一个long值,表示超时的数值。
第四个参数是:超时的时间单位。第三个和第四个一起,即线程空闲多久时间单位后,该线程会被终止。
第五个参数是:等待处理的任务队列,即悬挂任务队列。
ThreadPoolExecutor类中包含有线程池的一些统计信息方法,如最大线程数,核心线程数等,也包含一些线程的管理方法。
所有的上述三个方法都有一个重载的指定ThreadFactory的方法,这些重载方法的作用是用指定的线程工厂生成加入线程池的线程。
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory); }
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory)); }
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), threadFactory); }
- Java基本线程机制(二)
- java多线程系列----------- 基本的线程机制(二)
- 基本的线程机制(二)
- java基本线程机制
- Java基本线程机制(一)
- Java基本线程机制(三)
- Java基本线程机制(四)
- Java synchronized同步线程机制(二)
- Java线程的基本机制
- java多线程系列----------- 基本的线程机制(一)
- 从头认识java-18.2 基本的线程机制(5)-守护线程与非守护线程
- Java 并发:基本的线程机制
- Java并发(1) 基本的线程机制
- Java并发之基本的线程机制
- Java并发编程-1 基本线程机制
- Java线程生命周期与基本操作(二)
- 从头认识java-18.2 基本的线程机制(3)-线程的返回与sleep
- 基本的线程机制(一)
- 百度搜索风云榜Rss
- 汉字转换为拼音
- 编译MTK android源代码的过程
- Zygote进程简介
- Linux USB驱动详解
- Java基本线程机制(二)
- MongoDB:mongodb的安装和增删改查入门
- 用GNS3模拟Cisco ASA
- poj 2457 Part Acquisition
- 实例解析 用linux操作系统构建的路由器
- C++数学计算库与软件
- 上拉电阻与下拉电阻的作用
- 不是所有的MapReduce程序都要在MapReduce上执行
- 开源组织和社区概述小结