Java线程池实现原理之自定义线程池(一)
1.队列的概念
谈到多线程先讲下队列的概念,之后的多线程学习会用到此类知识。
队列分为:阻塞式队列(有界)、非阻塞式队列(无界),遵循着先进先出、后进后出的原则。
阻塞队列与非阻塞队列区别:
1.非阻塞式队列超出队列总数会丢失。
2.阻塞式队列超出总数会进入等待(等待时间=设置超时时间)。
3.获取队列方面:非阻塞式队列,如果为空返回null。阻塞式队列,如果为空也会进入等待。
非阻塞式队列ConcurrentLinkedDeque
//非阻塞式队列 无界(可以声明无限个队列)
public static void test1(){ ConcurrentLinkedDeque<Object> objects = new ConcurrentLinkedDeque<>();
objects.offer("java001");
objects.offer("java002"); System.out.println("队列总数:"+objects.size()); //建议:获取队列之后删除
System.out.println("获取队列但不删除:"+objects.peek());
System.out.println("获取队列但不删除,队列总数:"+objects.size());
System.out.println("获取队列删除:"+objects.poll()); //非阻塞式队列,如果为空返回null
System.out.println(objects.poll());
System.out.println(objects.poll());
System.out.println(objects.poll());
System.out.println("获取队列删除,队列总数:"+objects.size());
}
阻塞式队列ArrayBlockingQueue
//阻塞式队列
public static void test2() throws InterruptedException { long startTime=System.currentTimeMillis();
ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue<>(3);
arrayBlockingQueue.offer("A001",3, TimeUnit.SECONDS);
arrayBlockingQueue.offer("A002",3, TimeUnit.SECONDS); //阻塞式队列超出总数等待(等待时间=设置超时时间)
arrayBlockingQueue.offer("A003",3, TimeUnit.SECONDS);
arrayBlockingQueue.offer("A004",1, TimeUnit.SECONDS);
arrayBlockingQueue.offer("A005",1, TimeUnit.SECONDS); System.out.println("队列总数:"+arrayBlockingQueue.size());
System.out.println(arrayBlockingQueue.poll());
System.out.println(arrayBlockingQueue.poll());
System.out.println(arrayBlockingQueue.poll());
//阻塞式队列,如果为空也会等待。
System.out.println(arrayBlockingQueue.poll(1, TimeUnit.SECONDS));
System.out.println("队列剩余总数:"+arrayBlockingQueue.size()); System.out.println("耗时:"+ (System.currentTimeMillis() - startTime)/1000 +"秒"); }
2.线程池
线程池好处:
1.降低资源 => 重复利用机制 (降低创建线程和销毁线程)
2.提高响应效率 => 当任务到达时,任务可以不需要等待去创建线程就可以执行
3.方便管理 => 无限创建线程消耗资源、降低系统稳定性。使用线程池可以统一分配、调优、监控。
线程与任务的区别:
可以把线程理解成一个工作人员。而任务就是这个工作人员干的活。比如,餐厅的工作人员在为顾客传菜,传菜就是个任务。 Java中线程就是Thread类或其子类的一个实例。
也就是说你不必关注线程对象是用哪种方法创建的。在此基础上,线程所执行的代码,即run方法中的代码所实现的处理逻辑,
比如读取数据库中的一条记录,就是一个任务。因此,所谓任务是一个相对的概念。一个任务可以是读取数据库中的一条记录,
也可以是FTP传输一批文件,FTP传输一个文件……
//创建线程四种方式:
//1.可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
//2.定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
//3.可定时线程池,支持定时及周期性任务执行。
//4.单例线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
public static void test1() { //1.可缓存、定时、定长、单例
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i <10 ; i++) {
final int i1 = i;
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+",i:"+ i1);
}
});
} } public static void test2() { //2.可定长线程,核心线程5个,最多创建5个线程 (只会创建5个线程,其他线程共享这5个线程)
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i <10 ; i++) {
final int i1 = i;
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+",i:"+ i1);
}
});
}
} public static void test3() { long l = System.currentTimeMillis();
//3.可定时线程 =>核心线程数3 (延迟三秒执行)
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
for (int i = 0; i <10 ; i++) { final int i1 = i;
scheduledExecutorService.schedule(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+",i:"+ i1);
System.out.println("耗时:"+ (System.currentTimeMillis() -l)/1000 +"秒" );
}
},3, TimeUnit.SECONDS);
} } public static void test4() { //4.单例线程 =>核心线程数1 最大线程数1
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i <10 ; i++) {
final int i1 = i;
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+",i:"+ i1);
}
});
}
}
Java线程池实现原理之自定义线程池(一)的更多相关文章
- 线程池的原理以及实现线程池的类ExecutorService中方法的使用
1.线程池:线程池就是就像一个容器,而这个容器就是用来存放线程的,且有固定的容量. 如果没有线程池,当需要一个线程来执行任务时就需要创建一个线程,我们设创建线程的时间为t1,执行线程的时间为t2,销毁 ...
- JDBC连接池原理、自定义连接池代码实现
首先自己实现一个简单的连接池: 数据准备: CREATE DATABASE mybase; USE mybase; CREATE TABLE users( uid INT PRIMARY KEY AU ...
- 【Java EE 学习 15】【自定义数据库连接池之动态代理的使用】
一.动态代理的作用 使用动态代理可以拦截一个对象某个方法的执行,并执行自定义的方法,其本质是反射 优点:灵活 缺点:由于其本质是反射,所以执行速度相对要慢一些 二.数据库连接池设计思想 1.为什么要使 ...
- Java 多线程 自定义线程辅助
之前的文章我介绍了C#版本的多线程和自定义线程处理器. 接下来我们来看看Java版本的呢 java 的线程和C#的线程有点区别,java的线程没有是否是后台线程一说,具体原因是java的线程是jvm的 ...
- Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池
前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...
- Executors提供的四种线程池和自定义线程池
JAVA并发编程——EXECUTORS 线程池的思想是一种对象池的思想,开放一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理.当有线程任务时,从池中取一个,执行完毕,对象 ...
- 一个自定义线程池的小Demo
在项目中如果是web请求时候,IIS会自动分配一个线程来进行处理,如果很多个应用程序共享公用一个IIS的时候,线程分配可能会出现一个问题(当然也是我的需求造成的) 之前在做项目的时候,有一个需求,就是 ...
- 自定义线程池的名称(ThreadPoolExecutor)
目的:有时候为了快速定位出现错误的位置,在采用线程池时我们需要自定义线程池的名称. 1.创建ThreadFactory(ThreadPoolExecutor默认采用的是DefaultThreadFac ...
- c# 多线程系列二 自定义线程执行器
看了第一篇文章,多线程系列,看到了在线程执行任务队列有了一定的了解~! 那么今天我来讲讲,怎么样构建通用的自定义线程概念! 线程执行任务,肯定要有目标,但是如果写死了,那么一个线程处理执行职能按照思路 ...
随机推荐
- jmeter笔记(2)--组件介绍
1.测试计划 测试计划(Test Plan)是使用JMeter进行测试的起点,它是其它JMeter测试元件的容器. 2.Threads(Users)-线程组 每个测试需求的必备组件,是用来模拟用户并发 ...
- Pandas系列(十一)-文件IO操作
数据分析过程中经常需要进行读写操作,Pandas实现了很多 IO 操作的API,这里简单做了一个列举. 格式类型 数据描述 Reader Writer text CSV read_ csv to_cs ...
- DirectX11 With Windows SDK--22 立方体映射:静态天空盒的读取与实现
前言 这一章我们主要学习由6个纹理所构成的立方体映射,以及用它来实现一个静态天空盒. 但是在此之前先要消除两个误区: 认为这一章的天空盒就是简单的在一个超大立方体的六个面内部贴上天空盒纹理: 认为天空 ...
- 第二节:重写(new)、覆写(overwrite)、和重载(overload)
一. 重写 1. 关键字:new 2. 含义:子类继承父类中的普通方法,如果在子类中重写了一个和父类中完全相同的方法,子类中会报警告(问是否显式的隐藏父类的中的方法),如果在子类中的方法前加上new关 ...
- 解决Ubuntu 17.10设置面板打不开的问题
问题描述 对于Ubuntu桌面系统我用得不多,最近安装了Ubuntu17.10使用,一直都没遇到什么大的问题,界面风格已经与Windows很相似,总体体验还不错.直到某一天我突然手痒痒把Dock面板从 ...
- luogu 2154 离散化+杨辉三角+树状数组
将纵向固定,每次在横向找两个点,计算其中间墓地的贡献答案,离散化后同一行的预处理个数, 树状数组内存储C[up[i]][k] * C[down[i][k] 的值,每次更新时 down[横坐标]++; ...
- 程序通过ReportViewer对象来调用reporting services并导出pdf文件
ReportViewer tempReportViewer = new ReportViewer(); tempReportViewer.ProcessingMode = ProcessingMode ...
- ADO五大对象
ADO.NET五大对象, 1. Connection:与数据源建立连接. 2. Command:对数据源执行SQL命令并返回结果. 3. DataReader:读取数据源的数据,只允许对将数据源以只 ...
- 新手入门django本地化服务
自动化安装 #更新依赖库 pip install --upgrade setuptools #安装指定的版本 pip install Django==2.0.4 文 ...
- pythonのdjango Session体验
Session Django中默认支持Session,其内部提供了5种类型的Session供开发者使用: 数据库(默认)缓存文件缓存+数据库加密cookie1.数据库Session Django默认支 ...