线程池是多线程学习中需要重点掌握的.

系统启动一个新线程的成本是比较高的,因为它涉及与操作系统交互.在这种情形下,使用线程池可以很好的提高性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用线程池.

一.如何创建线程池??

在Java5之前,线程池都是开发才手动实现的,从Java5开始,Java内建支持线程池.主要是新增了一个executors工厂类来生产线程池.

1.newCachedThreadPool():创建一个具有缓存功能的线程池,系统根据需要创建线程,这些线程将会被缓存到线程池中.

2.newFixedThreadPool(int nThreads):创建一个可重用的,具有固定线程数的线程池.

3.newSingleThreadExecutor():创建一个只有单线程的线程池,它相当于调用newFixedThreadPool()方法传入参数为1;

4.newScheduledThreadPool(int corePoolSize)指池中所保存的线程数,即使线程是空闲的也被保存在线程池内;

5.newSingleThreadScheduledExecutor():创建只有一个线程的线程池,它可以在指定延迟后执行线程任务;

上面5个方法中的前3个方法返回一个ExecutorService对象,该对象代表一个线程池,它可以执行Runnable对象或Callable对象所代表的线程;而后2个方法返回一个ScheduledExecutorService线程池,它是ExecutorService的子类.

二.如何使用线程池?

举例:

  1. package com.amos.concurrent;
  2.  
  3. import java.util.List;
  4. import java.util.concurrent.ExecutorService;
  5. import java.util.concurrent.Executors;
  6. import java.util.concurrent.TimeUnit;
  7.  
  8. /**
  9. * @ClassName: ThreadPoolTest
  10. * @Description: java5中的线程池
  11. * @author: amosli
  12. * @email:hi_amos@outlook.com
  13. * @date Apr 21, 2014 2:13:27 AM
  14. */
  15. public class ThreadPoolTest {
  16.  
  17. public static void main(String[] args) {
  18. // ExecutorService executorService = Executors.newFixedThreadPool(3);//设置固定的线程数
  19. // ExecutorService executorService = Executors.newCachedThreadPool();//创建带缓存的线程池,自动分配线程数
  20. ExecutorService executorService = Executors.newSingleThreadExecutor();//创建单一线程池,如何实现线程死了,马上自动重新建一个
  21. Executors.newScheduledThreadPool(3).schedule(new Runnable() {//创建一个有3个线程数的线程池,批定3秒后执行run方法里的内容
  22. public void run() {
  23. System.out.println("bomb.....");
  24. }
  25. }, 3, TimeUnit.SECONDS );//隔3秒
  26.  
  27. for (int i = 0; i < 10; i++) {//创建10个任务
  28. final int task = i;
  29. executorService.execute(new Runnable() {//执行任务的线程
  30. public void run() {
  31. for (int i = 0; i < 10; i++) {//循环执行10个次
  32. System.out.println(Thread.currentThread().getName() + " loop" + i + " task is" + task);
  33. }
  34. }
  35. });
  36. }
  37. System.out.println("all of 10 task has committed!!");
  38. List<Runnable> shutdownNow = executorService.shutdownNow();//立即关闭线程,并返回未执行的线程
  39. System.out.println("closed thread size:"+shutdownNow.size());
  40. for(Runnable a:shutdownNow){
  41. System.out.println(a);
  42. }
  43. }
  44. }

运行效果:

创建一个单一的线程池,将任务加入了线程池,被关闭的线程有9个,在3秒后执行了输出'bomb....'

三.线程池使用注意事项

1.日常开发中Executors.newFixedThreadPool()是比较常用到的.

2.如何定时执行任务?

在执行指定时间执行任务时,比如要在中午12:00时运行一次,那么可以schedule(task, date.getTime() -
 System.currentTimeMillis(), TimeUnit.MILLISECONDS).也即时采用倒计时的方式去执行定时操作,这个是Java官方文档建议使用的.

3.扩展---每隔2秒运行一次任务,持续一个小时

  1. package com.amos.concurrent;
  2.  
  3. import static java.util.concurrent.TimeUnit.SECONDS;
  4.  
  5. import java.util.Date;
  6. import java.util.concurrent.Executors;
  7. import java.util.concurrent.ScheduledExecutorService;
  8. import java.util.concurrent.ScheduledFuture;
  9.  
  10. class BeeperControl {
  11. private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
  12. public void beepForAnHour() {
  13. final Runnable beeper = new Runnable() {
  14. public void run() {
  15. System.out.println(new Date().getSeconds());//计时
  16. System.out.println("beep");
  17. }
  18. };
  19. final ScheduledFuture beeperHandle = scheduler.scheduleAtFixedRate(beeper, 10, 2, SECONDS);//任务,10s delay,2s/次,单位秒
  20.  
  21. scheduler.schedule(new Runnable() {
  22. public void run() {
  23. beeperHandle.cancel(true);//撤消任务
  24. }
  25. }, 60 * 60, SECONDS);//60*60s=60min=1h
  26. }
  27. }
  28. public class test{
  29. public static void main(String[] args) {
  30. System.out.println(new Date().getSeconds());//计时
  31. new BeeperControl().beepForAnHour();
  32. }
  33. }

这个例子,是java官方提供的,这里稍做了修改,运行效果如下:

注:第一次运行是在0秒,10秒后开始第一次beep,然后每隔2秒beep一次;

这里首先是创建一个任务线程池: Executors.newScheduledThreadPool(1),设置了线程数为1,然后实现了一个runnable接口,再然后就是调用了scheduleAtFixedRate方法,指定频率,指定延时,执行beep任务,最后又实现了一个runnable接口,延时1小时执行撤消线程的任务.

java核心知识点学习----重点学习线程池ThreadPool的更多相关文章

  1. java核心-多线程(6)-线程池-ThreadPoolExecutor

    1.java多线程编程少不了使用线程池,线程池相关的工具类所在jdk包,java.util.concurrent 2.使用示例 demo1 public class ThreadPoolDemo { ...

  2. Java核心知识点学习----使用Condition控制线程通信

    一.需求 实现线程间的通信,主线程循环3次后,子线程2循环2次,子线程3循环3次,然后主线程接着循环3次,如此循环3次. 即:A->B->C---A->B->C---A-> ...

  3. Java核心知识点学习----线程中如何创建锁和使用锁 Lock,设计一个缓存系统

    理论知识很枯燥,但这些都是基本功,学完可能会忘,但等用的时候,会发觉之前的学习是非常有意义的,学习线程就是这样子的. 1.如何创建锁? Lock lock = new ReentrantLock(); ...

  4. Java核心知识点学习----多线程中的阻塞队列,ArrayBlockingQueue介绍

    1.什么是阻塞队列? 所谓队列,遵循的是先进先出原则(FIFO),阻塞队列,即是数据共享时,A在写数据时,B想读同一数据,那么就将发生阻塞了. 看一下线程的四种状态,首先是新创建一个线程,然后,通过s ...

  5. Java并发包源码学习系列:线程池ScheduledThreadPoolExecutor源码解析

    目录 ScheduledThreadPoolExecutor概述 类图结构 ScheduledExecutorService ScheduledFutureTask FutureTask schedu ...

  6. 【转】Java学习---深入理解线程池

    [原文]https://www.toutiao.com/i6566022142666736131/ 我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很 ...

  7. Java核心知识点 --- 线程中如何创建锁和使用锁 Lock , 设计一个缓存系统

    理论知识很枯燥,但这些都是基本功,学完可能会忘,但等用的时候,会发觉之前的学习是非常有意义的,学习线程就是这样子的. 1.如何创建锁? Lock lock = new ReentrantLock(); ...

  8. JUC源码学习笔记5——线程池,FutureTask,Executor框架源码解析

    JUC源码学习笔记5--线程池,FutureTask,Executor框架源码解析 源码基于JDK8 参考了美团技术博客 https://tech.meituan.com/2020/04/02/jav ...

  9. C#多线程学习 之 线程池[ThreadPool](转)

    在多线程的程序中,经常会出现两种情况: 一种情况:   应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应                   这一般使用ThreadPo ...

  10. C#多线程学习 之 线程池[ThreadPool]

    在多线程的程序中,经常会出现两种情况: 一种情况:   应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应                   这一般使用ThreadPo ...

随机推荐

  1. HackerRank "Prim's (MST) : Special Subtree"

    An intuitive Prim algorithm impl. #include <vector> #include <iostream> #include <que ...

  2. 使用Python xlwt写excel文件

    如果需要使用Python写Excel文件,首先下载或者安装xlwt. pip install xlwt 下面的这些demo应该可以帮助开发者快速上手使用xlwt写Excel文件: 创建工作簿(work ...

  3. Orcal学习

    sqlplus有几种登陆方式 比如:1.C: > sqlplus "/as sysdba" --以操作系统权限认证的oracle sys管理员登陆2.C: > sqlp ...

  4. ThinkPad E440 加内存后导致开不了机

    上周五新买的ThinkPad E440,原装内存是4G DDR3 1600Hz,明显不够用,于是在京东上买了一根南亚易胜的4G DDR3 1600Hz.安装之后正常开机,明显感觉速度快了很多.可是用了 ...

  5. spring Transaction Propagation 事务传播

    spring Transaction中有一个很重要的属性:Propagation.主要用来配置当前需要执行的方法,与当前是否有transaction之间的关系. 我晓得有点儿抽象,这也是为什么我想要写 ...

  6. linux装载可执行程序简析

    朱宇轲 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 linux中主要 ...

  7. 在IIS8添加WCF服务支持

    最近在做Silverlight,Windows Phone应用移植到Windows 8平台,在IIS8中测试一些传统WCF服务应用,发现IIS8不支持WCF服务svc请求,后来发现IIS8缺少对WCF ...

  8. 27. Best Time to Buy and Sell Stock && Best Time to Buy and Sell Stock II && Best Time to Buy and Sell Stock III

    Best Time to Buy and Sell Stock (onlineJudge: https://oj.leetcode.com/problems/best-time-to-buy-and- ...

  9. Spark SQL External Data Sources JDBC简易实现

    在spark1.2版本中最令我期待的功能是External Data Sources,通过该API可以直接将External Data Sources注册成一个临时表,该表可以和已经存在的表等通过sq ...

  10. oracle 常见恢复

    author by :shawnloong 环境:windows 2008 r2 sp1 db:oracle 11g r2 做之前记得做个完整备份 ONFIGURE RETENTION POLICY ...