Java多线程与并发库高级应用-线程池
线程池
线程池的思想

线程池的概念与Executors类的应用
> 创建固定大小的线程池
> 创建缓存线程池
> 创建单一线程池(如何实现线程死掉后重新启动?)
关闭线程池
> shutdown 与 shutdownNow的比较
用线程池启动定时器
> 调用ScheduleExecutorService 的 schedule 方法,返回的ScheduleFuture对象可以取消任务。
> 支持间隔重复任务的定时方式,不直接支持决定定时的方法,需要转换成相对时间方式。
public class ThreadPoolTest {
public static void main(String[] args) {
// ExecutorService threadPool = Executors.newFixedThreadPool(3); //创建一个固定大小的线程池,线程池中有3个线程可以同时服务
//缓存线程池 线程池中的线程数是动态变化的,当所有线程处于服务状态时,还有需要被服务的任务,自动增加一个线程进行服务
//当任务执行完毕,线程处于空闲一段时间,超时后则自动回收销毁线程
// ExecutorService threadPool = Executors.newCachedThreadPool();
//创建一个只有一个线程的线程池,当这个线程挂掉时,可以自动生成一个线程来代替
//可以解决一个网上很多人问的问题(如何实现线程死掉后重新启动?)
ExecutorService threadPool = Executors.newSingleThreadExecutor();
for(int i = 0;i<10;i++){ //往线程池中扔10个任务
final int task = i;
threadPool.execute(new Runnable() { //往线程池中扔了一个任务
@Override
public void run() {
for(int j = 0;j<10;j++){
System.out.println(Thread.currentThread().getName()+" is loop of "+ j + "the task of "+task);
}
}
});
}
System.out.println("all of 10 tasks have committed");
//上述代码执行完后 没有结束,线程池中有3个线程一直存在,所以程序不会结束
//可以使用 threadPool.shutdown()
threadPool.shutdown(); //当线程池中线程执行完所有任务,所有线程处于空闲状态时,干掉所有线程,程序自结束
// threadPool.shutdownNow(); //立即把池子中所有线程干掉,无论任务是否干完
}
}
package com.java.juc; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* 一、线程池:提供了一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁额外的开销,提高了响应的速度。
*
* 二、线程池的体系结构:
* java.util.concurrent.Executor: 负责线程的使用与调度根接口。
* |--**ExecutorService 子接口:线程池的主要接口
* |--ThreadPoolExecutor 线程池的实现类
* |--ScheduledExecutorService 子接口:负责线程的调度
* |--ScheduledThreadPoolExecutor : 继承 ThreadPoolExecutor 实现ScheduledExecutorService
* 三、工具类:Executors
* ExecutorService newFixedThreadPool() :创建固定大小的线程池。
* ExecutorService newCachedThreadPool(): 创建无限大小的线程池,线程池中线程数量不固定,可根据需求自动更改。
* ExecutorService newSingleThreadPool() : 创建单个线程池,线程池中只有一个线程。
*
* ScheduledExecutorService newScheduledThreadPool() 创建固定大小的线程池,可以延迟或定时的执行任务。
*
*/
public class TestThreadPool {
public static void main(String[] args) {
//1.创建线程池
ExecutorService threadPool = Executors.newFixedThreadPool(5);
ThreadPoolDemo demo = new ThreadPoolDemo(); //2.为线程池中的线程分配任务
for(int i = 0;i<10;i++){
threadPool.submit(demo);
} //3.关闭线程池
threadPool.shutdown(); //等待现有线程池中的任务之心完毕,关闭线程池,在等待过程中不接收新的任务 }
} class ThreadPoolDemo implements Runnable{
private int i = 0;
@Override
public void run() {
while(i <= 100){
System.out.println(Thread.currentThread().getName() + " : " + i++);
}
}
}
可以在线程池中放一个Callable任务,并且可以过去到返回结果
package com.java.juc; import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; /**
* 一、线程池:提供了一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁额外的开销,提高了响应的速度。
*
* 二、线程池的体系结构:
* java.util.concurrent.Executor: 负责线程的使用与调度根接口。
* |--**ExecutorService 子接口:线程池的主要接口
* |--ThreadPoolExecutor 线程池的实现类
* |--ScheduledExecutorService 子接口:负责线程的调度
* |--ScheduledThreadPoolExecutor : 继承 ThreadPoolExecutor 实现ScheduledExecutorService
* 三、工具类:Executors
* ExecutorService newFixedThreadPool() :创建固定大小的线程池。
* ExecutorService newCachedThreadPool(): 创建无限大小的线程池,线程池中线程数量不固定,可根据需求自动更改。
* ExecutorService newSingleThreadPool() : 创建单个线程池,线程池中只有一个线程。
*
* ScheduledExecutorService newScheduledThreadPool() 创建固定大小的线程池,可以延迟或定时的执行任务。
*
*/
public class TestThreadPool {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//1.创建线程池
ExecutorService threadPool = Executors.newFixedThreadPool(5);
ThreadPoolDemo demo = new ThreadPoolDemo(); List<Future> futureList = new ArrayList<>(); for(int i = 0; i<10; i++){
Future<Integer> future = threadPool.submit(new Callable<Integer>() {
public Integer call(){
int num = 0;
for(int i = 0;i<=100;i++){
num+=i;
}
return num;
}
});
futureList.add(future);
} for(int i = 0;i<futureList.size();i++){
System.out.println(futureList.get(i).get());
} // //2.为线程池中的线程分配任务
// for(int i = 0;i<10;i++){
// threadPool.submit(demo);
// } //3.关闭线程池
threadPool.shutdown(); //等待现有线程池中的任务之心完毕,关闭线程池,在等待过程中不接收新的任务
}
} class ThreadPoolDemo implements Runnable{
private int i = 0;
@Override
public void run() {
while(i <= 100){
System.out.println(Thread.currentThread().getName() + " : " + i++);
}
}
}
5050
5050
5050
5050
5050
5050
5050
5050
5050
5050
用线程池启动定时器
Executors.newScheduledThreadPool(3).schedule(
new Runnable() {
@Override
public void run() {
System.out.println("bombing!");
}
},
10,
TimeUnit.SECONDS);
还可以在上述代码中添加固定频率
//固定频率 10秒后触发,每隔两秒后执行一次
Executors.newScheduledThreadPool(3).scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
System.out.println("bombing!");
}
},
10,
2,
TimeUnit.SECONDS);
//在使用scheduleAtFixedRate 时java api没有提供在某个时间点触发,但API中提示可以通过计算,得到触发的事件点
// For example, to schedule at a certain future date,
// you can use: schedule(task, date.getTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS).
Java多线程与并发库高级应用-线程池的更多相关文章
- Java多线程与并发库高级应用-java5线程并发库
java5 中的线程并发库 主要在java.util.concurrent包中 还有 java.util.concurrent.atomic子包和java.util.concurrent.lock子包 ...
- Java多线程与并发库高级应用-Callable与Future的应用
Callable这种任务可以返回结果,返回的结果可以由Future去拿 >Future取得的结果类型和Callable返回的结果类型必须一致,这是通过泛型来实现的. >Completion ...
- Java多线程与并发库高级应用-传统线程机制回顾
1.传统线程机制的回顾 1.1创建线程的两种传统方式 在Thread子类覆盖的run方法中编写运行代码 // 1.使用子类,把代码放到子类的run()中运行 Thread thread = new T ...
- Java多线程与并发库高级应用-传统线程同步通信技术
面试题: 子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,接着又 主线程循环100次,如此循环50次,请写出程序 /** * 子线程循环10次,接着主线程循环100次,接着又回到 ...
- Java多线程与并发库高级应用-传统线程互斥技术
线程安全问题: 多个线程操作同一份数据的时候,有可能会出现线程安全问题.可以用银行转账来解释. 模拟线程安全问题 /** * 启动两个线程分别打印两个名字,名字按照字符一个一个打印 * * @aut ...
- Java多线程与并发库高级应用-工具类介绍
java.util.concurrent.Lock 1.Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互 ...
- Java多线程与并发库高级应用-同步集合
ArrayBlockingQueue LinkedBlockingQueue 数组是连续的一片内存 链表是不连续的一片内存 传统方式下用Collections工具类提供的synchronizedCo ...
- Java多线程与并发库高级应用-面试题
第一题:现有的程序代码模拟产生了16个日志对象,并且需要运行16秒才能打印完这些日志,请在程序中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,程序只需要运行4秒即可打印完这些日 ...
- Java多线程与并发库高级应用-可阻塞的队列
ArrayBlockQueue 可阻塞的队列 > 队列包含固定长度的队列和不固定长度的队列. > ArrayBlockQueue > 看BlockingQueue类的帮助文档,其中有 ...
随机推荐
- IT教程网
这个IT教程网(印度),我认为是最好的.里面的知识基础实用,覆盖面很广,作为IT入门和了解都是极好的. http://www.tutorialspoint.com/
- Exchange WebSerivce Usage
//ExchangeService版本为2007SP1 ExchangeService service = new ExchangeService(ExchangeVersion.Exchange20 ...
- codevs1910 递归函数
难度等级:黄金 codevs1910 递归函数 题目描述 Description 对于一个递归函数w(a, b, c). 如果a <= 0 or b <= 0 or c <= 0就返 ...
- 扩展 easyui 控件系列:为datagrid 增加过滤行
此功能还为真正完成,起到抛砖引玉的效果,发动大家的力量把这个功能完善起来,效果图如下: 基本上就是扩展了 datagrid.view 中的onAfterRender 这个事件,具体代码如下: $.ex ...
- vbs外部调用
一.QTP调用外部VBS的方法 加到QTP的Resource中 在QTP菜单中设置, 菜单FileàSettingsàResource,将要加载的VB脚本添加进来. 举例: 步骤1:在D盘下新建一个V ...
- Python2.7-异常和工具
来自<python学习手册第四版>第七部分,而且本书发布的时候3.1还未发布,所以针对本书的一些知识会有些滞后于python的版本,具体更多细节可以参考python的标准手册. 一.异常基 ...
- C/C++实践笔记_002编译和链接
1.要卡死程序用异步,同步的话开一个就关一个值为非0死循环.预处理优先于编译,别称预编译main函数死循环2.程序总是从main函数开始执行的C语言本身不提供输入输出语句print等来自于stdio库 ...
- EditPlus怎样自动换行
如果只是使用快捷键Ctrl+Shift+W或者使用文档→自动换行,的话,关闭软件之后再次打开时就会重新出现不能自动换行的问题. 中文版的是:文档→固定值设置(文档 菜单的最后一个),会打开一个“工具→ ...
- 【SQL语句】 - Ctrl+3 查询表属性的存储过程
/**-- ============================================= Author: xft CteateDate: 2013-10-11 Description:查 ...
- 78 mount 挂载Linux系统外的文件。
语法 mount [-hV] mount -a [-fFnrsvw] [-t vfstype] mount [-fnrsvw] [-o options [,...]] device | dir mou ...