博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浅析java中的四种线程池
阅读量:5302 次
发布时间:2019-06-14

本文共 8277 字,大约阅读时间需要 27 分钟。

 

1.使用线程池的好处

  

2.JUC中几种常用的线程池

  java.util.concurrent包下的Executors工厂类,提供了一系列的线程池的创建方法,其构造方法如下:

public ThreadPoolExecutor(int corePoolSize,              //线程池线程核心数量,线程池维护线程的最少数量                              int maximumPoolSize,               //线程池最大线程数量                              long keepAliveTime,           //空闲线程存活时间                              TimeUnit unit,              //存活时间的时间单位                              BlockingQueue
workQueue,  //存储任务的线程队列 ThreadFactory threadFactory,      //线程工厂 RejectedExecutionHandler handler) { //拒绝策略 if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }

其中常用的线程池有四种,分别是fixedThreadPool、cachedThreadPool、ScheduledThreadPool和SingleThreadExecutor。他们分别适用在不同的场合。

2.1  newFixedThreadPool

特点:

    • 用于创建一个可重用、固定线程数量的线程池;
    • 当线程池中线程都处于运行中时,新来的线程会进入等待状态,直到线程池中出现一个空闲线程;
    • 当一个线程在任务中途退出、终止时,会有一个新的线程来替代它继续完成后面未完成的任务。
    • 除非采用显式关闭的方法去关闭某个线程,否则线程会一直存在,不会释放资源。
    • 任务存储在无界阻塞队列中
    • 适用场景:长期任务

构造方法:

public static ExecutorService newFixedThreadPool(int nThreads) {        return new ThreadPoolExecutor(nThreads, nThreads,                                      0L, TimeUnit.MILLISECONDS,                                      new LinkedBlockingQueue
()); }

 

实例代码:  

import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import org.junit.Test;public class ExecutorsTest extends Thread{    private int index;    public ExecutorsTest(int i)     {        this.index = i;    }        public void run()     {        try         {            System.out.println("[Thread"+this.index+"]" +"start..");            Thread.sleep((int)(Math.random()*10000));            System.out.println("[Thread"+this.index+"]" + "end");        }catch(Exception e)         {            e.printStackTrace();        }    }                        public static void main(String args[])     {        ExecutorService service = Executors.newFixedThreadPool(4);                for(int i=0;i<10;i++)         {            service.execute(new ExecutorsTest(i));        }        service.shutdown();                }}

 

因为线程池中线程数量一共有4个,所以当一次有大于4个的任务需要执行时,因为线程池中无空闲线程,后续任务进入等待状态,当其他任务执行完毕后,线程空闲,则马上开始执行正在等待的任务。

 

2.1  newCachedThreadPool

特点:

  • 线程池数量上限为:Integer.MaxValue(2147483647);
  • 线程池默认空闲60S,超过60S会从线程池中移除;
  • 新来任务时,先检查是否有空闲线程可使用,若无,则创建一个新线程执行任务;
  • 任务存储在同步队列中。
  • 适用场景:短时异步任务。

构造函数:

public static ExecutorService newCachedThreadPool() {        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,                                      60L, TimeUnit.SECONDS,                                      new SynchronousQueue
()); }

示例代码:

1 import java.util.concurrent.ExecutorService; 2 import java.util.concurrent.Executors; 3  4 import org.junit.Test; 5  6 public class ExecutorsTest extends Thread{ 7     private int index; 8     public ExecutorsTest(int i)  9     {10         this.index = i;11     }12     13     public void run() 14     {15         try 16         {17             System.out.println("[Thread"+this.index+"]" +"start..");18             Thread.sleep((int)(Math.random()*1000));19             System.out.println("[Thread"+this.index+"]" + "end");20         }catch(Exception e) 21         {22             e.printStackTrace();23         }24     }25             26         27     28     public static void main(String args[]) 29     {30         ExecutorService service = Executors.newCachedThreadPool();31         32         for(int i=0;i<10;i++) 33         {34             service.execute(new ExecutorsTest(i));35         }36         try {37             Thread.sleep(1000);38         } catch (InterruptedException e) {39             // TODO Auto-generated catch block40             e.printStackTrace();41         }42         43         for(int i=0;i<5;i++) 44         {45             service.execute(new ExecutorsTest(i));46         }47         48         service.shutdown();    49         50     }

 创建10个工作线程用于处理任务,当线程执行完毕后,处于空闲状态,此时若出现新的任务,则会从线程池中用空闲的线程来处理新的任务。若没有空闲线程,则开启新线程处理。

 

2.3  newSingleThreadExecutor

特点:

  • 创建一个单个Worker的线程;
  • 线程会按照顺序依次执行;
  • 任务存储在无界阻塞队列中
  • 适用场景:需要按照顺序执行的任务。

构造方法:

public static ExecutorService newSingleThreadExecutor() {        return new FinalizableDelegatedExecutorService            (new ThreadPoolExecutor(1, 1,                                    0L, TimeUnit.MILLISECONDS,                                    new LinkedBlockingQueue
())); }

 实例代码:

import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import org.junit.Test;public class ExecutorsTest extends Thread{    private int index;    public ExecutorsTest(int i)     {        this.index = i;    }        public void run()     {        try         {            System.out.println("[Thread"+this.index+"]" +"start..");            Thread.sleep((int)(Math.random()*1000));            System.out.println("[Thread"+this.index+"]" + "end");        }catch(Exception e)         {            e.printStackTrace();        }    }                public static void main(String args[])     {        ExecutorService service = Executors.newSingleThreadExecutor();                for(int i=0;i<10;i++)         {            service.execute(new ExecutorsTest(i));        }        service.shutdown();                }}

 出现多个任务时,SingleThreadExecutor会按照顺序依次执行各个任务。

 

2.4 newScheduledThreadPool

 特点:

  • 任务存储在无界延迟队列中
  • 适用场景:需要定期执行或延迟执行的任务

构造方法:

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {        return new ScheduledThreadPoolExecutor(corePoolSize);    }    public ScheduledThreadPoolExecutor(int corePoolSize) {        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,              new DelayedWorkQueue());    }

实例代码一(scheduleAtFixedRate的使用)

import java.util.Date;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;public class ExecutorsTest2 extends Thread{    private int index;    public ExecutorsTest2()     {    }        public void run()     {        try         {            System.out.println("[Current Time is "+new Date().toString());                    }catch(Exception e)         {            e.printStackTrace();        }    }                    public static void main(String args[])     {        /*         * 执行定时任务newScheduledThreadPool         */        ScheduledExecutorService service = Executors.newScheduledThreadPool(10);                //5秒后开始执行,每隔一秒执行一次        service.scheduleAtFixedRate(new ExecutorsTest2(), 5, 1, TimeUnit.SECONDS);    }}

scheduleAtFixedRate方法,一共四个参数,分别是:需要执行的任务task、延迟执行时间t1、每次执行任务的时间间隔t2、时间间隔单位。 含义是:在t1时间过后,以 1次/t2 的频率来不断执行 task。 上述代码中,在5秒延迟后,以 1次/1秒的频率执行 打印当前时间的任务。

实例代码二scheduleWithFixedDelay的使用):

1 import java.util.Date; 2 import java.util.concurrent.Executors; 3 import java.util.concurrent.ScheduledExecutorService; 4 import java.util.concurrent.TimeUnit; 5  6 public class ExecutorsTest3 extends Thread{ 7     private int index; 8     public ExecutorsTest3()  9     {10     }11     12     public void run() 13     {14         try 15         {16             //每次任务大约耗时1秒17             Thread.sleep(1000);18             System.out.println("[Current Time is "+new Date().toString());19             20         }catch(Exception e) 21         {22             e.printStackTrace();23         }24     }25                 26     public static void main(String args[]) 27     {28         /*29          * 执行定时任务newScheduledThreadPool30          */31         ScheduledExecutorService service = Executors.newScheduledThreadPool(10);32         33         //5秒后开始执行,每次任务执行完后延迟3秒后,继续执行下一次34         service.scheduleWithFixedDelay(new ExecutorsTest3(), 5, 3, TimeUnit.SECONDS);35     }36 }

 

scheduleWithFixedDelay也是四个参数,分别是:待执行的任务Task,延迟时间t1,每次任务执行完毕后延迟t2秒后执行下次任务,延迟时间单位。

转载于:https://www.cnblogs.com/LearnAndGet/p/10096660.html

你可能感兴趣的文章
二级指针内存模型
查看>>
bzoj千题计划140:bzoj4519: [Cqoi2016]不同的最小割
查看>>
GitHub开源项目SlidingMenu简介
查看>>
栈的链表实现
查看>>
HTML5实现全兼容的下拉刷新功能
查看>>
一次 Mysql 字符集的报错,最后让我万马奔腾!!!
查看>>
cmd 里面运行git提示“不是内部或外部命令,也不是可运行的程序”的解决办法...
查看>>
给网页标题添加小图标
查看>>
Effective Scala
查看>>
Tasks and jobs
查看>>
python小程序之一
查看>>
数据解析
查看>>
Spring Ioc原理
查看>>
关于深拷贝与浅拷贝的一些简单说明
查看>>
TCP三次握手和四次握手
查看>>
js 鼠标事件
查看>>
AnsiString用法(转)
查看>>
DP E - Cheapest Palindrome
查看>>
用TTL线在CFE环境下拯救半砖wrt54g路由器
查看>>
soundpool
查看>>