Java高并发编程(四)
一、Executor执行器
1.Executor接口,java线程池框架中的顶层接口,提供一个execute方法来执行任务
import java.util.concurrent.Executor;
public class T01_MyExecutor implements Executor {
public static void main(String[] args) {
new T01_MyExecutor().execute(()->System.out.println("hello executor"));
}
@Override
public void execute(Runnable command) {
//new Thread(command).run();//另起线程方法调用
command.run();//方法直接调用
}
}
2.任务接口
1)callable接口:提供一个call方法,具有返回值可以抛出异常
2)runnable接口:提供一个run方法,无返回值不可抛出异常
3.ExecutorService接口(Executor的一个子接口)
1)ExecutorService可以理解为服务,执行execute方法可以向服务器中添加runnable任务无返回值,而执行submit方法可以向服务中添加callable与runnable任务,且有返回值
2)Executor与ExecutorService的简单理解:可以想象许多的执行器Executor在等待着执行任务,而service服务可通过调用execute或submit方法来添加不同的任务供执行器执行
3)submit方法具有一个future类型的返回值,与callable,Executors一起使用
public class T06_Future {
public static void main(String[] args) throws InterruptedException, ExecutionException {
FutureTask<Integer> task = new FutureTask<>(()->{
TimeUnit.MILLISECONDS.sleep(500);
return 1000;
}); //new Callable () { Integer call();}
new Thread(task).start();
System.out.println(task.get()); //阻塞
//*******************************
ExecutorService service = Executors.newFixedThreadPool(5);
Future<Integer> f = service.submit(()->{
TimeUnit.MILLISECONDS.sleep(500);
return 1;
});
System.out.println(f.get());
System.out.println(f.isDone());
}
}
运行结果:

4.Executors(操作Executor的一个工具类、工厂类)
二、ThreadPool线程池
1.线程池将任务分配给池中线程,当线程池中线程执行不过来时,任务会进入等待队列,队列由BlockingQueue实现,当有线程空闲时再来任务时会被分配给空闲线程,一个线程同时维护着两个队列(结束队列与等待队列)
下面一个程序帮助理解线程池的概念
public class T05_ThreadPool {
public static void main(String[] args) throws InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(5); //execute submit
for (int i = 0; i < 6; i++) {
service.execute(() -> {
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
});
}
System.out.println(service);
service.shutdown();//正常关闭,等待所有任务执行完毕,关闭线程池
System.out.println(service.isTerminated());//判断所有任务是否都执行完了
System.out.println(service.isShutdown());//判断线程池是否被关闭了
System.out.println(service);
TimeUnit.SECONDS.sleep(5);
System.out.println(service.isTerminated());
System.out.println(service.isShutdown());
System.out.println(service);
}
}
运行结果:

2.六种线程池
1)FixedThreadPool 固定线程数量的线程池
2)cachedThreadPool 假定刚开始一个线程都没有,来一个任务开启一个线程,如果再来一个任务,线程池中有空闲线程就将任务分配给空闲线程,如此往复直到起到电脑能支撑限度为止,默认一个线程空闲超过一分钟就自动销毁
3)singleThreadPool 线程池中只有一个线程
4)scheduledThreadPool 定时器线程池
5)workStealingPool 工作窃取线程池,当前线程池有线程空闲,会自动去寻找任务执行,默认根据CPU核数启动默认线程数目线程,是精灵(demon)线程(守护线程、后台线程),主函数不阻塞的话看不到输出,本质上是ForkJoinPool实现的
6)ForkJoinPool 分叉合并线程,大任务可以切分成许多的小任务,如果小任务还是太大的话还可以继续分,分的可以了就将小任务合并,最后产生一个总的结果(有点像归并排序)
ForkJoinTask从RecursiveAction和RecursiveTask继承
a.RecursiveAction 无返回值
/**
* 对数组中所有数求和
* @author zhangqi
*
*/
public class T12_ForkJoinPool {
static int[] nums = new int[1000000];
static final int MAX_NUM = 50000;
static Random r = new Random(); static {
for(int i=0; i<nums.length; i++) {
nums[i] = r.nextInt(100);
} System.out.println(Arrays.stream(nums).sum()); //stream api
} static class AddTask extends RecursiveAction { int start, end; AddTask(int s, int e) {
start = s;
end = e;
} @Override
protected void compute() { if(end-start <= MAX_NUM) {
long sum = 0L;
for(int i=start; i<end; i++) sum += nums[i];
System.out.println("from:" + start + " to:" + end + " = " + sum);
} else { int middle = start + (end-start)/2; AddTask subTask1 = new AddTask(start, middle);
AddTask subTask2 = new AddTask(middle, end);
subTask1.fork();
subTask2.fork();
} } } /*static class AddTask extends RecursiveTask<Long> { int start, end; AddTask(int s, int e) {
start = s;
end = e;
} @Override
protected Long compute() { if(end-start <= MAX_NUM) {
long sum = 0L;
for(int i=start; i<end; i++) sum += nums[i];
return sum;
} int middle = start + (end-start)/2; AddTask subTask1 = new AddTask(start, middle);
AddTask subTask2 = new AddTask(middle, end);
subTask1.fork();
subTask2.fork(); return subTask1.join() + subTask2.join();
} }*/ public static void main(String[] args) throws IOException {
ForkJoinPool fjp = new ForkJoinPool();
AddTask task = new AddTask(0, nums.length);
fjp.execute(task);
//long result = task.join();
//System.out.println(result); System.in.read(); }
}
运行结果:

b.RescursiveTask 有返回值的递归任务
/**
* 对数组中所有数求和
* @author zhangqi
*
*/
public class T12_ForkJoinPool {
static int[] nums = new int[1000000];
static final int MAX_NUM = 50000;
static Random r = new Random(); static {
for(int i=0; i<nums.length; i++) {
nums[i] = r.nextInt(100);
} System.out.println(Arrays.stream(nums).sum()); //stream api
} /* static class AddTask extends RecursiveAction { int start, end; AddTask(int s, int e) {
start = s;
end = e;
} @Override
protected void compute() { if(end-start <= MAX_NUM) {
long sum = 0L;
for(int i=start; i<end; i++) sum += nums[i];
System.out.println("from:" + start + " to:" + end + " = " + sum);
} else { int middle = start + (end-start)/2; AddTask subTask1 = new AddTask(start, middle);
AddTask subTask2 = new AddTask(middle, end);
subTask1.fork();
subTask2.fork();
} } }*/ static class AddTask extends RecursiveTask<Long> { int start, end; AddTask(int s, int e) {
start = s;
end = e;
} @Override
protected Long compute() { if(end-start <= MAX_NUM) {
long sum = 0L;
for(int i=start; i<end; i++) sum += nums[i];
return sum;
} int middle = start + (end-start)/2; AddTask subTask1 = new AddTask(start, middle);
AddTask subTask2 = new AddTask(middle, end);
subTask1.fork();
subTask2.fork(); return subTask1.join() + subTask2.join();
} } public static void main(String[] args) throws IOException {
ForkJoinPool fjp = new ForkJoinPool();
AddTask task = new AddTask(0, nums.length);
fjp.execute(task);
long result = task.join();
System.out.println(result); //System.in.read(); }
}
运行结果:

补充:
ThreadPoolExecutor线程池执行器(自定义线程池,许多线程池的底层实现,ForkJoinPool不是由它实现)
Java高并发编程(四)的更多相关文章
- [ 高并发]Java高并发编程系列第二篇--线程同步
高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...
- java高并发编程(一)
读马士兵java高并发编程,引用他的代码,做个记录. 一.分析下面程序输出: /** * 分析一下这个程序的输出 * @author mashibing */ package yxxy.c_005; ...
- 关于Java高并发编程你需要知道的“升段攻略”
关于Java高并发编程你需要知道的"升段攻略" 基础 Thread对象调用start()方法包含的步骤 通过jvm告诉操作系统创建Thread 操作系统开辟内存并使用Windows ...
- Java高并发编程基础三大利器之CountDownLatch
引言 上一篇文章我们介绍了AQS的信号量Semaphore<Java高并发编程基础三大利器之Semaphore>,接下来应该轮到CountDownLatch了. 什么是CountDownL ...
- java高并发编程(三)
java高并发主要有三块知识点: synchronizer:同步器,在多个线程之间互相之间怎么进行通讯,同步等: 同步容器:jdk提供了同步性的容器,比如concurrentMap,concurren ...
- java高并发编程(四)高并发的一些容器
摘抄自马士兵java并发视频课程: 一.需求背景: 有N张火车票,每张票都有一个编号,同时有10个窗口对外售票, 请写一个模拟程序. 分析下面的程序可能会产生哪些问题?重复销售?超量销售? /** * ...
- java高并发编程(五)线程池
摘自马士兵java并发编程 一.认识Executor.ExecutorService.Callable.Executors /** * 认识Executor */ package yxxy.c_026 ...
- java高并发编程(二)
马士兵java并发编程的代码,照抄过来,做个记录. 一.分析下面面试题 /** * 曾经的面试题:(淘宝?) * 实现一个容器,提供两个方法,add,size * 写两个线程,线程1添加10个元素到容 ...
- java高并发编程基础之AQS
引言 曾经有一道比较比较经典的面试题"你能够说说java的并发包下面有哪些常见的类?"大多数人应该都可以说出 CountDownLatch.CyclicBarrier.Sempah ...
随机推荐
- GO入门——3. 控制语句
1 if 条件表达式没有括号 支持一个初始化表达式(可以是并行方式) 左大括号必须和条件语句或else在同一行 支持单行模式 初始化语句中的变量为block级别,同时隐藏外部同名变量 a := 1 i ...
- Chapter 3 Phenomenon——24
My mom was in hysterics, of course. 我的母亲当时是歇斯底里的发疯了. I had to tell her I felt fine at least thirty t ...
- epoll 触发模式
Edge Triggered (ET):边缘触发只有数据到来,才触发,不管缓存区中是否还有数据.Level Triggered (LT):水平触发只要有数据都会触发. LT(level trigger ...
- mongo学习使用记录2 spring data
spring data mongo 打印mongo NoSql语句 log4j.properties log4j.rootLogger=INFO, stdout log4j.logger.org.sp ...
- vscode浏览器打开html vscode修改默认浏览器
vscode怎么浏览器打开html预览?这里大家可以通过安装open in browser插件解决. 1.vscode怎么浏览器预览 1.点击拓展 2.输入open in browser,选择第一个 ...
- Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope <-错误解决方案
做项目的时候因为懒,在写service时直接复制了控制器的依赖注入,之后就出现了这个错误,查了半天. 解决其实很简单,删除掉service中注入的$scope即可.
- 【转】常见六大Web 安全攻防解析
原文转自:https://segmentfault.com/a/1190000018073845 作者:浪里行舟 在互联网时代,数据安全与个人隐私受到了前所未有的挑战,各种新奇的攻击技术层出不穷.如何 ...
- 深入出不来nodejs源码-从fs.stat方法来看node架构
node的源码分析还挺多的,不过像我这样愣头完全平铺源码做解析的貌似还没有,所以开个先例,从一个API来了解node的调用链. 首先上一张整体的图,网上翻到的,自己懒得画: 这里的层次结构十分的清晰, ...
- 【Java基础】7、Java同步机制之Monitor监视器与syncrhoized实现原理
一:Monitor Monitor是一个同步工具,相当于操作系统中的互斥量(mutex),即值为1的信号量. 它内置与每一个Object对象中,相当于一个许可证.拿到许可证即可以进行操作,没有拿到则需 ...
- Entity Framework系列文章目录
Entity Framework系列文章目录Entity Framework系列文章目录Entity Framework系列文章目录Entity Framework系列文章目录