12、线程池的作用和Executor类:
线程池是为突然大量爆发的线程设计的,通过有限的几个固定线程为大量的操作服务,减少了创建和销毁线程所需的时间,从而提高效率。
如果一个线程的时间非常长,就没必要用线程池了(不是不能作长时间操作,而是不宜。),况且我们还不能控制线程池中线程的开始、挂起、和中止。Executor这个类是一个工厂类,用来生成不同特点的ExecutorService或 ScheduledExecutorService实例。这里主要介绍这些不同特点的实例不同在什么地方。
3类不同的ExecutorService实例. static ExecutorService newSingleThreadExecutor() 启动一个线程负责任务顺序执行,顺序意味着先提交的任务先执行。其原理是:任务会被提交到一个队列里,启动的那个线程会从队里里取任务,然后执行, 执行完,再从队列里取下一个任务,再执行。如果该线程执行一个任务失败,并导致线程结束,系统会创建一个新的线程去执行队里里后续的任务,不会因为前面的 任务有异常导致后面无辜的任务无法执行。
static ExecutorService newCachedThreadPool() 启动N个线程处理N个任务。既然是多个线程运行,意味着任务不会顺序运行。一个任务完成后,该线程空闲60秒会被结束。新提交的任务会发现空闲线程,并使用它,如果没有空闲线程可用则创建新线程。其实,这就是一个动态线程池。适合于规模比较小、创建较频繁的任务。
static ExecutorService newFixedThreadPool(int nThreads) 动态线程池不限制线程的数量,在有些情况下我们不希望线程数量不可控,则可以使用拥有固定线程数目的线程池。运作原理是:任务被提交到一个队列里排 队,线程池里的空闲线程会把队列里的任务提出来执行,每个线程执行完一个任务后,就去队列里抓另一个任务出来执行。如果一个线程由于失败而终止,系统会创 建另一个线程执行后续任务。
带ThreadFactory参数生成的ExecutorService实例。以上3种实例创建工作线程时都是用的默认的线程工厂类来创建。也可 以指定自己的线程工厂类来创建,以newSingleThreadExecutor(ThreadFactory threadFactory)为例: //你自己的实现 class YourselfThreadFactory implements ThreadFactory { public Thread newThread(Runnable r) { Thread thread = new Thread(r); doXXX; return thread; } } newSingleThreadExecutor 与 newFixedThreadPool(1) 区别. JavaDoc上说:Unlike the otherwise equivalent newFixedThreadPool(1) the returned executor is guaranteed not to be reconfigurable to use additional threads.
什么意思?不懂。为什么?不具体。具体一下就懂了。
((ThreadPoolExecutor)newFixedThreadPool(1)).setCorePoolSize(3); 即newFixedThreadPool(1)可以后期修改线程数,不能保证线程只有一个。而newSingleThreadExecutor可以保证。
static Callablecallable(Runnable task) 把Runnable任务转换成Callable任务.例子如下
public static void test() throws Exception { Runnable task = new Runnable() { public void run() { log(*begin task*); try { Thread.sleep(1000); } catch (InterruptedException e) { } log(*end task*); } }; Callable c = Executors.callable(task); ExecutorService service = Executors.newCachedThreadPool(); Future f = service.submit(c); System.out.println(f.get());//返回null log(*end*); } private static void log(String message) { System.out.println(new Date() + *: * + message); } public static void main(String args[]) throws Exception { test(); }
JDK1.5引入的concurrent包使多线程编写更加容易、代码更容易理解、可读性更好.
http://www.cnblogs.com/taven/archive/2011/12/17/2291469.html