java自定义线程池池,线程池使用及自定义线程池

一 案例引申

编写代码同时只允许五个线程并发访问(以下文的函数为例子)

private static void method() {

System.out.println("ThreadName" + Thread.currentThread().getName() + "进来了");

Thread.sleep(2000);

System.out.println("ThreadName" + Thread.currentThread().getName() + "出去了");

}

思考:

1 若果使用 synchronized的话避免了并发安全问题,但是不满足题目的要求,因为题目要求一次让五个线程访问,使用锁的时候一次只能访问一个。

2 解决思路:使用信号量或者使用线程池

二 信号量的简单使用(了解)

package ThreadPool;

import java.util.concurrent.*;

import java.util.concurrent.atomic.AtomicInteger;

/**

* Create by SunnyDay on 2018/11/27

*/

public class ThreadPoolDemo {

//信号量 Doug Lea 大牛写的(concurrent并发包下面的东西都是他写的) 参数控制并发线程的个数

private static Semaphore semaphore = new Semaphore(5);

public static void main(String[] args) {

for (int i = 0; i < 100; i++) {

new Thread(new Runnable() {

@Override

public void run() {

try {

method();

} catch (InterruptedException e) {

}

}

}).start();

}

private static void method() throws InterruptedException {

// 首先获取一把锁

semaphore.acquire();

System.out.println("ThreadName" + Thread.currentThread().getName() + "进来了");

Thread.sleep(2000);

System.out.println("ThreadName" + Thread.currentThread().getName() + "出去了");

// 释放锁

semaphore.release();

}

三 使用线程池解决(了解)

package ThreadPool;

import java.util.concurrent.Executor;

import java.util.concurrent.Executors;

/**

* Create by SunnyDay on 2018/11/27

* 使用线程池解决

*/

public class ThreadPool {

/**

* java 提供了线程池的创建工具类( Executors),

* 我们可以通过工具类创建不同的线程池

*/

private static Executor executor = Executors.newCachedThreadPool();//缓冲线程池

private static Executor executor2 = Executors.newFixedThreadPool(5);//固定线程池

private static Executor executor3 = Executors.newScheduledThreadPool(5);//计划任务线程池

private static Executor executor4 = Executors.newSingleThreadExecutor();//单个线程池(池中只有一个线程)

public static void main(String[] args) {

for (int i = 0; i < 100; i++) {

// 线程池的简单使用(十分简单) 调用execute方法传递参数类型为runnable类型即可

executor2.execute(new Runnable() {

@Override

public void run() {

try {

method();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

});

}

}

private static void method() throws InterruptedException {

System.out.println("ThreadName" + Thread.currentThread().getName() + "进来了");

Thread.sleep(2000);

System.out.println("ThreadName" + Thread.currentThread().getName() + "出去了");

}

}

四 自定义线程池

1 小发现

/**

* 查看随便几个个线程池的源码:

* public static ExecutorService newCachedThreadPool() {

* return new ThreadPoolExecutor(0, Integer.MAX_VALUE,

* 60L, TimeUnit.SECONDS,

* new SynchronousQueue());

* }

*

* 发现都是对线程池类(ThreadPoolExecutor)进行了简单的封装(传的参数不一致)

*/

2 ThreadPoolExecutor构造( 以6个参数的为例子)

* @param corePoolSize 核心池大小 int

* @param maximumPoolSize 最大池大小 int

* @param keepAliveTime 保活时间 long(任务完成后要销毁的延时)

* @param unit 时间单位 决定参数3的单位,枚举类型的时间单位

* @param workQueue 工作队列 用于存储任务的工作队列(BlockingQueue接口类型)

* @param threadFactory 线程工厂 用于创建线程

*

* */

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue workQueue,

ThreadFactory threadFactory) {

this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,

threadFactory, defaultHandler);

}

3 自定义实现案例

package ThreadPool;

import java.util.concurrent.*;

import java.util.concurrent.atomic.AtomicInteger;

/**

* Create by SunnyDay on 2018/11/27

*/

public class ThreadPoolDemo {

public static void main(String[] args) {

/**手写线程池

* @param corePoolSize 核心池大小 int

* @param maximumPoolSize 最大池大小 int

* @param keepAliveTime 保活时间 long(任务完成后要销毁的延时)

* @param unit 时间单位 决定参数3的单位,枚举类型的时间单位

* @param workQueue 工作队列 用于存储任务的工作队列(BlockingQueue接口类型)

* @param threadFactory 线程工厂 用于创建线程

*

*线程不是越多越好,google工程师推荐 线程个数=cpu核心数+1(例如四核的开5个线程最好)

* */

// 参数任务上限

LinkedBlockingQueue blockingQueue = new LinkedBlockingQueue<>(100);

ThreadFactory threadFactory = new ThreadFactory() {

// int i = 0; 用并发安全的包装类

AtomicInteger atomicInteger = new AtomicInteger(1);

@Override

public Thread newThread(Runnable r) {

//创建线程 吧任务传进来

Thread thread = new Thread(r);

// 给线程起个名字

thread.setName("MyThread" + atomicInteger.getAndIncrement());

return thread;

}

};

ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 10, 1, TimeUnit.SECONDS, blockingQueue, threadFactory);

for (int i = 0; i < 100; i++) {

pool.execute(new Runnable() {

@Override

public void run() {

try {

method();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

});

}

}

/**

* 编写代码(如下文的函数)同时只允许五个线程并发访问:

*

* 1 若果使用 synchronized的话避免了并发安全问题,但是不满足题目的要求,

* 因为题目要求一次让五个线程访问,使用锁的时候一次只能访问一个。

* 2 解决思路:使用信号量或者使用线程池

*

* 3 自己手动封装线程池(明白启动策略)

*/

private static void method() throws InterruptedException {

System.out.println("ThreadName" + Thread.currentThread().getName() + "进来了");

Thread.sleep(2000);

System.out.println("ThreadName" + Thread.currentThread().getName() + "出去了");

}

}

五 线程池补充

1 启动策略草图

d7d41e1ae40d

image.png

2 流程图(摘抄)

d7d41e1ae40d

image.png

六 总结

通过上面的总结相信对线程池的概念,使用,启动策略,大致的有了一些了解,但是这些还是不够的,想要深入了解还需我们不懈的努力探讨!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/541810.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

impala和mysql语法,impala CREATE TABLE语句

CREATE TABLE语句用于在Impala中的所需数据库中创建新表。 创建基本表涉及命名表并定义其列和每列的数据类型。语法以下是CREATE TABLE语句的语法。 这里&#xff0c;IF NOT EXISTS是一个可选的子句。 如果使用此子句&#xff0c;则只有在指定数据库中没有具有相同名称的现有表…

Java二维数组谷电,java二维数组遍历的2种代码

二维数组遍历&#xff1a;思想&#xff1a;1.先将二维数组中所有的元素拿到2.再将二维数组中每个元素进行遍历&#xff0c;相当于就是在遍历一个一维数组第一种方法&#xff1a;双重for循环//遍历二维数组public class Traverse_a_two_dimensional_array {public static void m…

MATLAB元胞自动机报告,元胞自动机概述与MATLAB实现

什么是元胞自动机&#xff1f;元胞自动机(cellular automata&#xff0c;CA) 是一种时间、空间、状态都离散&#xff0c;空间相互作用和时间因果关系为局部的网格动力学模型&#xff0c;具有模拟复杂系统时空演化过程的能力。它能构建随时间推移发生状态转移的系统&#xff0c;…

php session redis db,php session redis 配置

具体环境&#xff1a;一台apachephp的服务器(yum安装remi源及配置 httpd-2.2.15 php-5.4.45)一台redis服务器(yum安装remi源及配置 redis-3.2.6)保证apache服务器可以访问redis服务器的6379端口具体步骤&#xff1a;1、在apachephp服务器上安装redis扩展点击(此处)折叠或打开yu…

(四)其他的说明

2019独角兽企业重金招聘Python工程师标准>>> 关于日志&#xff0c;主要是利用aop来实现的。cn.demoframe.test.frame.service.LogAspect&#xff0c;这里在方法前做了个切面setReqReachTime&#xff0c;设置了一个请求达到时间。接下来还有个切面&#xff0c;是在co…

vm中linux物理内存不足解决方案

为什么80%的码农都做不了架构师&#xff1f;>>> 之前创建的一个center os,默认是8GB&#xff0c;经过一顿折磨&#xff0c;装jdk,tomcat,redis,mycat,nginx,mysql,hadoop...终于&#xff0c;内存不足了&#xff0c;在使用docker build某镜像的时候。迭代懵逼了&am…

.7z.001,.7z.002这样的文件如何解压

1 如图所示&#xff0c;压缩分卷没有显示关联的软件来打开&#xff0c;Winrar右击也无法解压 2 可以使用7-ZIP软件打开该文件&#xff0c;然后选择提取&#xff08;相当于Winrar的解压&#xff09;&#xff0c;然后选择提取路径&#xff0c;默认是同一个文件夹&#xff0c;点击…

php中文网视频放不了,【杂谈】看php中文网视频课程的正确姿势!

看在线课程如何集中精力学习&#xff1f;ki4网为你分享看ki4网视频课程的正确姿势&#xff01;不谈理论给些实用建议&#xff0c;可以根据你的情况多尝试&#xff0c;看看哪条对你有用&#xff01;1、选一门自己有兴趣而且教师讲得好的课程。(点击学习&#xff1a;ki4网视频教程…

怎么查看我的php版本,怎样查看php版本

怎样查看php版本方法一&#xff1a;命令行查询如果已经配置好环境变量&#xff0c;直接在命令行中输入php -v&#xff0c;将会显示php的版本信息。如果没有配置环境变量&#xff0c;直接在命令行中进入到php的安装目录后&#xff0c;再输入命令php -v&#xff0c;如图所示是我在…

xor在PHP是什么意思,?=‘在PHP中是什么意思?

万千封印因为它不会增加任何价值echo&#xff0c;我认为您希望了解PHP中的确切含义&#xff1a;Array([0] > Array([0] > 368 // T_OPEN_TAG_WITH_ECHO[1] > [2] > 1)[1] > Array([0] > 309 // T_VARIABLE[1] > $a [2] > 1)[2] > ; // U…

如何使用ES6中的参数

ECMAScript 6&#xff08;或者叫 ECMAScript 2015&#xff09;是 ECMAScript 的最新标准&#xff0c;极大的提高了 JavaScript 中处理参数的能力。现在我们可以使用 rest 参数&#xff08;rest parameters&#xff09;、默认值&#xff08;default values&#xff09;和解构&am…

php 代码 自动检查工具下载,PHP_CodeSniffer安装和使用教程(自动代码检查规范工具)...

在我们开发中都会讲究代码规范&#xff0c;若是个人开发者&#xff0c;代码规范与否&#xff0c;只要自己看得懂便可以了&#xff0c;但是在团队协作中&#xff0c;代码规定尤为重要&#xff0c;下面&#xff0c;我们介绍一款PHP_CodeSniffer&#xff0c;自动检查代码规范的工具…

在Bootstrap中使用类的按钮类型

Bootstrap has 7 different types of buttons with contextual classes from which we can create buttons easily by using these classes (.btn-default, .btn-success, .btn-danger, .btn-primary, .btn-info, .btn-warning, .btn-link). Bootstrap具有上下文类型的 7种不同…

php json encode中文乱码,php json_encode中文乱码如何解决

php encode中文乱码的解决办法&#xff1a;首先打开相应的PHP文件&#xff1b;然后使用正则语句“preg_replace("#\\\u([0-9a-f]{4})#ie","iconv(UCS-2BE, UTF-8...)”将编码替换成中文即可。本文列举3个方法&#xff0c;实现json_encode()后的string显示中文问…

ORACLE JOB 失败 查看,Oracle JOB异常中断原因分析

注释今天研发同事找我确认 PKG_WMS.proc_TaskMain 存储的 job 是否还在运行&#xff0c;竟发现 dba_jobs.NEXT_DATE4000/1/1&#xff0c;如下看看究竟原因吧~JOB 信息&#xff1a;参数&#xff1a;BROKEN : 中断标记 ,N 启动、Y 中断 --> DBMS_JOBS.BROKEN(job_id,TRUE/FA…

步骤1:JMeter 录制脚本接口测试

JMeter 常用测试方法简介 1.下载安装 http://jmeter.apache.org/download_jmeter.cgi 安装JDK&#xff0c;配置环境变量JAVA_HOME. 系统要求&#xff1a;JMeter2.11 需要JDK1.6以上的版本支持运行 2.学习Jmeter元件 http://jmeter.apache.org/usermanual/component_reference.h…

多例模式

多例&#xff1a;只是单例的一种延伸 不必过于在意各种模式的名字&#xff0c;重要的是学会融会贯通&#xff0c;把生产的car放到集合中 类似JDBC 的连接池 把连接对象放到池中 多例模式特点&#xff1a; 1. 多例类可以有多个实例 2. 多例类必须自己创建自己的实例&a…

Oracle public view,【易错概念】以太坊Solidity函数的external/internal,public/private,view/pure/payable区别...

1. 函数类型&#xff1a;内部(internal)函数和外部(external)函数函数类型是一种表示函数的类型。可以将一个函数赋值给另一个函数类型的变量&#xff0c;也可以将一个函数作为参数进行传递&#xff0c;还能在函数调用中返回函数类型变量。 函数类型有两类&#xff1a;- 内部(i…

ftp连接oracle服务器,使用SSL加密连接FTP - 架建SSL安全加密的FTP服务器(图)_服务器应用_Linux公社-Linux系统门户网站...

四、使用SSL加密连接FTP启用Serv-U服务器的SSL功能后&#xff0c;就可以利用此功能安全传输数据了&#xff0c;但FTP客户端程序必须支持SSL功能才行。 如果我们直接使用IE浏览器进行登录则会出现图4显示的错误信息&#xff0c;一方面是以为没有修改默认的端口21为990&#xff0…

oracle 微信公众号,关于微信公众号贴代码的方法

微信公众号码上贴代码一直一来都是个头疼的问题。吐槽一句&#xff1a;要是后台编辑器支持markdown就好了。今天教大家用在线markdown排版工具&#xff0c;把代码完美贴到微信公众号上。长话短说&#xff0c;今天用到的两个工具&#xff1a;首先&#xff0c;以一段代码为例。假…