Java多线程之ExecutorService

讲到Java多线程,大多数人脑海中跳出来的是Thread、Runnable、synchronized……这些是最基本的东西,虽然已经足够强 大,但想要用好还真不容易。从JDK 1.5开始,增加了java.util.concurrent包,它的引入大大简化了多线程程序的开发(要感谢一下大牛Doug Lee)。

        java.util.concurrent包分成了三个部分,分别是java.util.concurrent、 java.util.concurrent.atomic和java.util.concurrent.lock。内容涵盖了并发集合类、线程池机制、同 步互斥机制、线程安全的变量更新工具类、锁等等常用工具。

        为了便于理解,本文使用一个例子来做说明,交代一下它的场景:

 假设要对一套10个节点组成的环境进行检查,这个环境有两个入口点,通过节点间的依赖关系可以遍历到整个环境。依赖关系可以构成一张有向图,可能存在环。为了提高检查的效率,考虑使用多线程。

1、Executors

        通过这个类能够获得多种线程池的实例,例如可以调用newSingleThreadExecutor()获得单线程的ExecutorService, 调用newFixedThreadPool()获得固定大小线程池的ExecutorService。拿到ExecutorService可以做的事情就 比较多了,最简单的是用它来执行Runnable对象,也可以执行一些实现了Callable<T>的对象。用Thread的start() 方法没有返回值,如果该线程执行的方法有返回值那用ExecutorService就再好不过了,可以选择submit()、invokeAll()或者 invokeAny(),根据具体情况选择合适的方法即可。

Executors

        虽然以上提到的接口有其实现的具体类,但为了方便Java5.0建议使用Executors的工具类来得到Executor接口的具体对象,需要注意的 是Executors是一个类,不是Executor的复数形式。Executors提供了以下一些static的方法:

callable(Runnable task):将Runnable的任务转化成Callable的任务

newSingleThreadExecutor:产生一个ExecutorService对象,这个对象只有一个线程可用来执行任务,若任务多于一个,任务将按先后顺序执行。

newCachedThreadPool():产生一个ExecutorService对象,这个对象带有一个线程池,线程池的大小会根据需要调整,线程执行完任务后返回线程池,供执行下一次任务使用。

newFixedThreadPool(int poolSize):产生一个ExecutorService对象,这个对象带有一个大小为poolSize的线程池,若任务数量大于poolSize,任务会被放在一个queue里顺序执行。

newSingleThreadScheduledExecutor:产生一个ScheduledExecutorService对象,这个对象的线程池大小为1,若任务多于一个,任务将按先后顺序执行。

newScheduledThreadPool(int poolSize):产生一个ScheduledExecutorService对象,这个对象的线程池大小为poolSize,若任务数量大于poolSize,任务会在一个queue里等待执行  

 

2. Atomics原子级变量

      原子量级的变量,主要的类有AtomicBoolean,AtomicInteger, AotmicIntegerArray, AtomicLong, AtomicLongArray,AtomicReference ……。这些原子量级的变量主要提供两个方法:

   compareAndSet(expectedValue, newValue):比较当前的值是否等于expectedValue,若等于把当前值改成newValue,并返回true。若不等,返回false。

   getAndSet(newValue):把当前值改为newValue,并返回改变前的值。

    这些原子级变量利用了现代处理器(CPU)的硬件支持可把两步操作合为一步的功能,避免了不必要的锁定,提高了程序的运行效率。

你可能感兴趣的:(executorService)