java线程池的创建使用

  利用java的多线程编程可以大大的提高系统的并发运行效率,线程越多并发执行的任务就越多,但是并不意味着效率会一直提高,相反会得到适得其反的效果。

  java中的多线程编程一共有三种方法:

    继承Thread类

    继承Runnable接口

    使用线程池Executor

  下面简单的介绍一些Executor的使用

 一、话不多说先上代码:

   创建一个线程数为3的线程池,模拟十个任务让线程池调度线程去完成。

 1 package executorExample;
 2 
 3 import java.util.concurrent.ExecutorService;
 4 import java.util.concurrent.Executors;
 5 
 6 public class Threads{
 7     private static final int nThreads = 3;
 8     private int i;
 9     public void Thread(){
10         //实现ExecutorService接口创建 线程数为三个的线程池
11         ExecutorService executorService = Executors.newFixedThreadPool(nThreads);
12         for (i = 0; i < 10; i++) {
13             //在匿名内部类中变量index还在必须把index声明成final类型
14             final int index = i;
15             executorService.execute(new Runnable() {
16                 @Override
17                 public void run() {
18                     // TODO Auto-generated method stub
19                     String threadName = Thread.currentThread().getName();//获取当前线程的名字
20                     System.out.println(threadName+"正在执行任务:"+index);
21                 }
22             });
23         }
24     }
25     public static void main(String[] args){
26         Threads thread = new Threads();
27         thread.Thread();
28     }
29 }

  接下来解释一下这段代码。在这段代码当中用到的关键词有ExcutorService,Executors,newFixedThreadPool和execute方法,还有一个最重要的Executor,现在来解释一下他们之间的关系

1、Executors

  首先我们先看一下Executors的源码

 1 public static ExecutorService newFixedThreadPool(int nThreads) {
 2         return new ThreadPoolExecutor(nThreads, nThreads,
 3                                       0L, TimeUnit.MILLISECONDS,
 4                                       new LinkedBlockingQueue<Runnable>());
 5  6 public static ExecutorService newWorkStealingPool(int parallelism) {
 7         return new ForkJoinPool
 8             (parallelism,
 9              ForkJoinPool.defaultForkJoinWorkerThreadFactory,
10              null, true);
11     }
12 public static ExecutorService newWorkStealingPool() {
13         return new ForkJoinPool
14             (Runtime.getRuntime().availableProcessors(),
15              ForkJoinPool.defaultForkJoinWorkerThreadFactory,
16              null, true);
17     }
18 public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
19         return new ThreadPoolExecutor(nThreads, nThreads,
20                                       0L, TimeUnit.MILLISECONDS,
21                                       new LinkedBlockingQueue<Runnable>(),
22                                       threadFactory);
23     }
 1 public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
 2     return new FinalizableDelegatedExecutorService
 3       (new ThreadPoolExecutor(1, 1,
 4                     0L, TimeUnit.MILLISECONDS,
 5                     new LinkedBlockingQueue<Runnable>(),
 6                     threadFactory));
 7 }
 8 public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
 9         return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
10                                       60L, TimeUnit.SECONDS,
11                                       new SynchronousQueue<Runnable>(),
12                                       threadFactory);
13     }

 

  里面有四种都是ExecutorService类型的线程池,也就是说,我们在创建线程池的时候可以有四种选择,newCachedThreadPool,newFixedThreadPool,newSingleThreadExecutor,newWorkStealingPool。其中最常用的就是newCatchedThreadPool和newFixedThreadPool,可以看到每个线程池的参数队列是不同的,LinkedBlockingQueue<Runnable>()属于无边界队列,

  (1)newFixedThreadPool

    是一个固定线程数的线程池,当线程池里线程满了之后,下载任务就会被阻塞到等待下载队列里面等待下载。而LinkedBlockingQueue<Runnable>()无限扩容的FIFO规则的队列,我们在编程的时候一般用它比较多。

  (2)newCatchedThreadPool

    是一个可缓存线程池,如果线程池里的线程数超过了处理需要,则线程池可以灵活的回收空闲的线程,

  别的线程池就先不介绍了

2、ExecutorService

 

1 public interface ExecutorService extends Executor {

  在接口ExecutorService的源码中我们可以看到继承了Executor类,并且在ExecutorService方法中实现了

    

void shutdown();
invokeAll();
submit();

 

  等等的方法。

3、Executor

1 public interface Executor {
2 
3     void execute(Runnable command);
4 }

  在接口Executor中只有一个execute()方法,这是用来将任务提交给线程的。

到这里就明白了他们之间的关系,这样可以帮助我们更好的利用线程池去提高我们的代码效率。

写的不是很完善,如果有大神,希望多多指教,写这个东西也是为了自己能够更熟练的使用线程池。

 

posted @ 2017-06-20 16:02  wjunhao博客  阅读(356)  评论(0编辑  收藏  举报