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

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

一.如何创建线程池??

在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的子类.

二.如何使用线程池?

举例:

package com.amos.concurrent;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; /**
* @ClassName: ThreadPoolTest
* @Description: java5中的线程池
* @author: amosli
* @email:hi_amos@outlook.com
* @date Apr 21, 2014 2:13:27 AM
*/
public class ThreadPoolTest { public static void main(String[] args) {
// ExecutorService executorService = Executors.newFixedThreadPool(3);//设置固定的线程数
// ExecutorService executorService = Executors.newCachedThreadPool();//创建带缓存的线程池,自动分配线程数
ExecutorService executorService = Executors.newSingleThreadExecutor();//创建单一线程池,如何实现线程死了,马上自动重新建一个
Executors.newScheduledThreadPool(3).schedule(new Runnable() {//创建一个有3个线程数的线程池,批定3秒后执行run方法里的内容
public void run() {
System.out.println("bomb.....");
}
}, 3, TimeUnit.SECONDS );//隔3秒 for (int i = 0; i < 10; i++) {//创建10个任务
final int task = i;
executorService.execute(new Runnable() {//执行任务的线程
public void run() {
for (int i = 0; i < 10; i++) {//循环执行10个次
System.out.println(Thread.currentThread().getName() + " loop" + i + " task is" + task);
}
}
});
}
System.out.println("all of 10 task has committed!!");
List<Runnable> shutdownNow = executorService.shutdownNow();//立即关闭线程,并返回未执行的线程
System.out.println("closed thread size:"+shutdownNow.size());
for(Runnable a:shutdownNow){
System.out.println(a);
}
}
}

运行效果:

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

三.线程池使用注意事项

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

2.如何定时执行任务?

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

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

package com.amos.concurrent;

import static java.util.concurrent.TimeUnit.SECONDS;

import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture; class BeeperControl {
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); public void beepForAnHour() {
final Runnable beeper = new Runnable() {
public void run() {
System.out.println(new Date().getSeconds());//计时
System.out.println("beep");
}
};
final ScheduledFuture beeperHandle = scheduler.scheduleAtFixedRate(beeper, 10, 2, SECONDS);//任务,10s delay,2s/次,单位秒 scheduler.schedule(new Runnable() {
public void run() {
beeperHandle.cancel(true);//撤消任务
}
}, 60 * 60, SECONDS);//60*60s=60min=1h
}
}
public class test{
public static void main(String[] args) {
System.out.println(new Date().getSeconds());//计时
new BeeperControl().beepForAnHour();
}
}

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

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

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

最新文章

  1. Vertica license导入最佳实践
  2. asynDBCenter(修改)
  3. http://www.mxchip.com/talk/news/jishuwenzhang/2014-09-11/67.html
  4. Codeforces Round #375 (Div. 2) ABCDE
  5. iOS 系统架构 &amp;&amp; 常用 framework
  6. Centos5.5系统备份
  7. aos.js超赞页面滚动元素动画jQuery动画库
  8. 自定义了一个email模块,符合大多数人的使用习惯
  9. Git .gitignore文件简介及使用
  10. IOS-43-导航栏标题navigationItem.title不能改变颜色的两种解决方法
  11. python一天一题(3)
  12. applyColorMap()研究(如果我对现有的colormap不满意,那么如何具体来做)
  13. UGUI 判断元素进入舞台
  14. Python 3 的安装
  15. 【laravel5.6】 laravel 接口 接管 自定义异常类
  16. [原]sublime Text2
  17. 阿里巴巴Java开发手册- 控制语句
  18. Foreda8上安装Ant1.9.2
  19. androidcookie
  20. JS把内容动态插入到DIV

热门文章

  1. 修改selinux出现setsebool: SELinux is disabled.的解决方法
  2. 关于git的基本使用
  3. ffmpeg &amp;&amp; nginx hls
  4. vue a href=&quot;tel&quot; 拨打电话
  5. Unit07: document 对象 、 自定义对象 、 事件
  6. JAVA-Unit04: SQL(高级查询)
  7. jmeter踩坑系列
  8. mysql实战优化之一:sql优化
  9. Oracle ASM操作管理
  10. mysql where语句中 or 和 and连用注意点