java 线程Thread 技术--1.5 Executor Executors,ThreadPool,Queue
Executors :
Executors ,就是一个线程工具类;大部分操作线程的方法,都可以在这个工具类中就行创建,执行,调用一些线程的方法;
Executor :
用于执行和提交一个runnable 任务;就是将线程的创建与执行就行了解藕:
像:
new Thread(new(RunnableTask())).start()}
可以被替代为
Executor executor = anExecutor;
executor.execute(new RunnableTask1());:
线程池 ThreadPool:
是我们维护线程数量的一个池子,创建的目的是为了节省系统资源,避免频繁创建线程与销毁线程带来的系统开销;接下来进行实例型的线程例子:
1. Executors.newFixedThreadPool(nthread); 创建一个固定数量的线程池
如果任务超出了线程的数量,那么多出的任务放在 LinkedBlockingQueue<Runnable>中,然后在这个队列中进行进行任务获取执行,先进先出;
尝试运行如下程序:
public static void main(String[] args) throws InterruptedException {
ExecutorService pool = Executors.newFixedThreadPool(3);
for(int i=0;i<6;i++) {
pool.submit(()->{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"....");});
}
System.out.println(pool.isTerminated());
System.out.println(pool);
Thread.sleep(4000);
System.err.println(pool);
pool.shutdown();
}
运行结果如下:
false
java.util.concurrent.ThreadPoolExecutor@eed1f14[Running, pool size = 3, active threads = 3, queued tasks = 3, completed tasks = 0]
pool-1-thread-1....
pool-1-thread-3....
pool-1-thread-2....
pool-1-thread-3....
pool-1-thread-1....
pool-1-thread-2....
java.util.concurrent.ThreadPoolExecutor@eed1f14[Running, pool size = 3, active threads = 0, queued tasks = 0, completed tasks = 6]
可以看到我们的线程池对象中:
pool size :大小就是我们定义的3个线程,且运行也是在这3个线程之内进行运行;
active thread:目前活动的线程
queued tasks :在队列中的线程数量
completed tasks :完成的线程数
运作机制:在 ThreadPoolExecutor类中维护着一个worker内部类的内部类来维护着线程的运行状态;
volatile long completedTasks;//统计已经执行完毕的线程数量
//可以看到使用了线程工厂ThreadFactory进行线程的创建,我们所有的任务都会在这里进行工作的分配
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
} /** Delegates main run loop to outer runWorker */
public void run() {
runWorker(this);
}
2.Executors.newCachedThreadPool() 创建缓存线程池;
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService pool = Executors.newCachedThreadPool();
Future<Integer> p1 = pool.submit(()->{ Thread.sleep(1000);System.out.println(Thread.currentThread().getName());return 2;});
Future<Integer> p2 = pool.submit(()->{ Thread.sleep(1000); System.out.println(Thread.currentThread().getName());return 3;});
Future<Integer> p3 = pool.submit(()->{ Thread.sleep(1000); System.out.println(Thread.currentThread().getName());return 4;});
Future<Integer> p4 = pool.submit(()->{ System.out.println(Thread.currentThread().getName());return 5;});
Future<Integer> p5 = pool.submit(()->{ System.out.println(Thread.currentThread().getName());return 6;});
Future<Integer> p6 = pool.submit(()->{ System.out.println(Thread.currentThread().getName());return 8;});
System.out.println(pool);
Thread.sleep(70000);
System.err.println(pool);
}
结果如下:
pool-1-thread-4
pool-1-thread-5
pool-1-thread-5
java.util.concurrent.ThreadPoolExecutor@41629346[Running, pool size = 5, active threads = 3, queued tasks = 0, completed tasks = 3]
pool-1-thread-1
pool-1-thread-2
pool-1-thread-3
java.util.concurrent.ThreadPoolExecutor@41629346[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 6]
得知CacheThreadPool会根据任务来创建不同个数的线程;没有空闲的线程就创建;有就重复使用
最大是integet.MAX_VALUE,线程超过60second 不使用,线程会被销毁;应用于并发很大,机器很牛逼;
3.Executors.newSingleThreadExecutor() :创建一个单个线程;顾名思义:就是所有的任务都放在一个线程中去执行,这样就保证了线程中任务运行的执行顺序,按照顺序进行执行;
public static void main(String[] args) {
ExecutorService pool = Executors.newSingleThreadExecutor();
Future<Integer> p1 = pool.submit(()->{ Thread.sleep(1000);System.out.println(Thread.currentThread().getName()+"...1");return 2;});
Future<Integer> p2 = pool.submit(()->{ Thread.sleep(1000); System.out.println(Thread.currentThread().getName()+"...2");return 3;});
Future<Integer> p3 = pool.submit(()->{ Thread.sleep(1000); System.out.println(Thread.currentThread().getName()+"...3");return 4;});
Future<Integer> p4 = pool.submit(()->{ System.out.println(Thread.currentThread().getName()+"...4");return 5;});
Future<Integer> p5 = pool.submit(()->{ System.out.println(Thread.currentThread().getName()+"...5");return 6;});
Future<Integer> p6 = pool.submit(()->{ System.out.println(Thread.currentThread().getName()+"...6");return 8;});
System.out.println(pool);
}
可以看到任务都是一条一条执行的;
4.Executors.newScheduledThreadPool(nthread) :用来执行定时任务的线程池,代替了timer
public static void main(String[] args) throws Exception{
ScheduledExecutorService schedule = Executors.newScheduledThreadPool(2);
//在指定时间内执行,只执行一次
ScheduledFuture<Integer> schedule2 = schedule.schedule(()-> {System.out.println(Thread.currentThread().getName());return 2;}, 3, TimeUnit.SECONDS);
//指定时间时间,并在一定的时间内去重复执行
schedule.scheduleAtFixedRate(()->{System.out.println(Thread.currentThread().getName());}, 1, 3, TimeUnit.SECONDS);
System.out.println(schedule);
Thread.sleep(10000);
System.out.println(schedule);
}
5. ForkJoinPool:可以将一个庞大的任务根据自己的规则将任务划分成不同的小块,ForkJoin会根据规则去开启线程去运行每一个小部分;
例子是计算0-2000000的和:使用extends RecursiveAction 这个没有返回值;
package com.java.baseknowledge.concurrent15; import java.io.IOException;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction; /**
* fork join pool
* 进行将一个大的任务根据自己的规则进行切分,用线程去执行
* 启动的线程是后台线程(精灵线程java 线程Thread 技术--1.5 Executor Executors,ThreadPool,Queue的更多相关文章
- java 线程Thread 技术--1.5 Future与Callable
Callable: 从官方文档说起: 通过实现callable 的called 方法可以使一个任务可以返回一个结果以及可能抛出一个异常: callable 与runnable 是相似的,可以被其他线程 ...
- java 线程Thread 技术--线程状态与同步问题
线程技术第三篇: 线程的状态: 1. 创建状态: 当用new 操作符创建一个新的线程对象时,该线程就处于创建状态,系统不为它分配资源 2.可运行状态:当线程调用start 方法将为线程分配必须的系统资 ...
- java 线程Thread 技术--volatile关键字
java 语言中允许线程访问共享变量,为了保证共享变量能被准确和一致的更新,Java 语言提供了volatile 关键字,也就是我们所说的内存一致性: 问题抛出:(尝试去运行下面代码,以及将volat ...
- java 线程Thread 技术--1.5Lock 与condition 演示生产者与消费模式
在jdk 1.5 后,Java 引入了lock 锁来替代synchronized ,在使用中,lock锁的使用更加灵活,提供了灵活的 api ,不像传统的synchronized ,一旦进入synch ...
- java 线程Thread 技术--方法演示生产与消费模式
利用wait 与notifyAll 方法进行演示生产与消费的模式的演示,我们两个线程负责生产,两个线程消费,只有生产了才能消费: 在effective Java 中有说过: 1. 在Java 中 ,使 ...
- java 线程Thread 技术--线程创建源码解释
永远不要忘记最基础的东西,只有把最基础的知识打牢靠,才能够使你走的更远,我将从今天开始,进行线程知识的回顾,一些常用知识点,以及java1.5 引入的并发库,进行详细的讲解与总结 创建线程的目的是为了 ...
- java 线程Thread 技术--线程方法详解
Thread 类常用的方法与Object类提供的线程操作方法:(一个对象只有一把锁
- java 线程Thread 技术--创建线程的方式
在第一节中,对线程的创建我们通过看文档,得知线程的创建有两种方式进行实现,我们进行第一种方式的创建,通过继承Thread 类 ,并且重写它的run 方法,就可以进行线程的创建,所有的程序执行都放在了r ...
- java线程池技术(二): 核心ThreadPoolExecutor介绍
版权声明:本文出自汪磊的博客,转载请务必注明出处. Java线程池技术属于比较"古老"而又比较基础的技术了,本篇博客主要作用是个人技术梳理,没什么新玩意. 一.Java线程池技术的 ...
随机推荐
- DOM节点的增删改查以及class属性的操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Java中Asm包有什么用?
ASM能做什么 我们都知道,一般情况下,Class文件是通过javac编译器产生的,然后通过类加载器加载到虚拟机内,再通过执行引擎去执行. 现在我们可以通过ASM的API直接生成符合Java虚拟机规范 ...
- HTML实现页面自动跳转的五种方法
下面列了五个例子来详细说明,这几个例子的主要功能是:在5秒后,自动跳转到同目录下的hello.html(根据自己需要自行修改)文件. 1)html的实现 复制代码 代码如下: <head> ...
- ReactiveX 学习笔记(19)使用 RxSwift + RxCocoa 进行 GUI 编程
课题 程序界面由3个文本编辑框和1个文本标签组成. 要求文本标签实时显示3个文本编辑框所输入的数字之和. 文本编辑框输入的不是合法数字时,将其值视为0. 3个文本编辑框的初值分别为1,2,3. 创建工 ...
- bug提单规范
一.提单模板 标题:[项目组][模块][子模块][发生原因]问题简要描述描述:[预置条件] 有就写清楚,没有就写无[操作步骤]1.XXXXX2.XXXXXX3.XXXXX[实际结果] XXXXX[预期 ...
- 二级菜单(avalon+jquery动画)
by 司徒正美 var vm = avalon.define({ $id: "test", array: [ { name: 111111, child: [ {name: 1.1 ...
- 深入jUI(DWZ)
-----------------------------------------------------------------------------主页面index.html <html& ...
- 【原创】逆向练习(CrackMe)
Write Up 登录的两个方法 方法1.用IDA分析 新版测试题.exe.在Strings Window中查找有一定意义的串. 从上面的窗口中,发现了CyberSwat和passwordisme这两 ...
- GIS工具-shp浏览器
GIS工具-shp浏览器 软件特点: 1. 单个文件,windows平台 2. 绿色,不用安装 3.C语言系列开发,非vb,.net,Java等,无需虚拟机,无需运行时,无需第三方工具 获取方法: 十 ...
- 主流浏览器 Cookie 的大小
目前测试的两种浏览器:Chrome 和 IE . 环境:IIS 7.5 只创建了站点,未做任何配置. Chrome : v36.0.1985.143 m 单个 Cookie 的长度为 4069 个字符 ...