100行Java代码构建一个线程池
Java自定义线程池的实现示例

Java⾃定义线程池的实现⽰例⽬录⼀、Java语⾔本⾝也是多线程,回顾Java创建线程⽅式如下:⼆、JDK线程池⼯具类.三、业界知名⾃定义线程池扩展使⽤.⼀、Java语⾔本⾝也是多线程,回顾Java创建线程⽅式如下:1、继承Thread类,(Thread类实现Runnable接⼝),来个类图加深印象。
2、实现Runnable接⼝实现⽆返回值、实现run()⽅法,啥时候run,⿊话了。
3、实现Callable接⼝重写call()+FutureTask获取.public class CustomThread {public static void main(String[] args) {// ⾃定义线程new Thread(new Runnable() {@Overridepublic void run() {System.out.println("Custom Run");System.out.println(Thread.currentThread().getName());}},"custom-thread-1").start();}}4、基于线程池集中管理创建线程系列周期.【本篇⽂章重点介绍】⼆、JDK线程池⼯具类.1、Executors⼯具类,是JDK中Doug Lea⼤佬实现供开发者使⽤。
随着JDK版本迭代逐渐加⼊了基于⼯作窃取算法的线程池了,阿⾥编码规范也推荐开发者⾃定义线程池,禁⽌⽣产直接使⽤Executos线程池⼯具类,因此很有可能造成OOM异常。
同时在某些类型的线程池⾥⾯,使⽤⽆界队列还会导致maxinumPoolSize、keepAliveTime、handler等参数失效。
因此⽬前在⼤⼚的开发规范中会强调禁⽌使⽤Executors来创建线程池。
这⾥说道阻塞队列。
LinkedBlockingQueue。
2、⾃定义线程池⼯具类基于ThreadPoolExecutor实现,那个JDK封装的线程池⼯具类也是基于这个ThreadPoolExecutor实现的。
java11的线程池写法

java11的线程池写法在Java 11中,线程池的写法可以通过使用`Executors`工厂类来创建不同类型的线程池。
下面我将介绍一些常见的线程池写法。
1. 创建固定大小的线程池:java.ExecutorService executor =Executors.newFixedThreadPool(5);这将创建一个固定大小为5的线程池,线程池中的线程数量始终保持不变,当有新任务提交时,如果线程池中有空闲线程,则立即执行,如果没有,则新任务会被暂存在一个任务队列中,待有线程空闲时再执行。
2. 创建单线程的线程池:java.ExecutorService executor =Executors.newSingleThreadExecutor();这将创建一个只有一个工作线程的线程池,所有任务按照它们被提交的顺序依次执行。
3. 创建可缓存的线程池:java.ExecutorService executor =Executors.newCachedThreadPool();这将创建一个可根据需要创建新线程的线程池,而且在先前构建的线程可用时将重用它们。
如果线程在60秒内未被使用,则将终止并从缓存中移除。
4. 创建定时执行任务的线程池:java.ScheduledExecutorService executor =Executors.newScheduledThreadPool(3);这将创建一个定时执行任务的线程池,可以在给定的延迟之后或者周期性执行任务。
在使用完线程池后,需要调用`shutdown()`方法来关闭线程池: java.executor.shutdown();这将拒绝新任务的提交,等待已经提交的任务执行完成(包括等待队列中的任务),并且不接受新的任务。
以上是在Java 11中常见的线程池写法,通过选择合适的线程池类型,可以更好地满足不同场景下的需求。
Java版线程池实现

Java版线程池实现线程池调度技术原理:package test.threadpool;import java.util.*;import test.cfg.*;public class ThreadPool {private int reserve = 0; //保留线程private int minPools = 10; //最小连接池数目,预启动线程数目private int maxActive = 70; //最多活动线程数目private int maxPools = 100; //最大连接池数目private int checkThreadPeriod = 5; //检查连接池的周期ArrayList m_ThreadList; //工作线程列表ArrayList m_ReserveList; //保留线程链表LinkedList m_RunList = null; //工作任务列表int freeThreadCount = 0;//未被使用的线程数目private java.util.Timer timer = null;//定时器static Object o = new Object();public void setMinPools(int minPools) {this.minPools = minPools;}public void setMaxPools(int maxPools) {this.maxPools = maxPools;}public void setCheckThreadPeriod(int checkThreadPeriod) {this.checkThreadPeriod = checkThreadPeriod;}/*** 初始化线程池,由于各个线程启动的时候是有一定的时间间隔,启动的时候会有一定的时间**/public ThreadPool() {// reserve = Integer.parseInt(FtpConfig.getValue("reserve"); //从配置文件中获取参数// minPools = Integer.parseInt(FtpConfig.getValue("minPools "); //从配置文件中获取参数//maxActive = Integer.parseInt(FtpConfig.getValue("maxActive "); //从配置文件中获取参数//maxPools = Integer.parseInt(FtpConfig.getValue("maxPools "); //从配置文件中获取参数//checkThreadPeriod = Integer.parseInt(FtpConfig// .getValue("monitorPeriod") * 60 * 1000; //以分为轮询单位m_ThreadList = new ArrayList(); //初始化工作线程链表m_ReserveList = new ArrayList();m_RunList = new LinkedList(); //初始化任务列表ArrayList list = null;if (reserve > 0)list = (ArrayList) FtpConfig.getProValueList("reserveList";for (int i = 0; i < reserve; i++) { //启动保留线程,根据配置链表中的线程列表启动对应的保留线程.保存的是线程的全路径//class nametry {Thread thr = (Thread) Class.forName((String) list. get(i)).newInstance();m_ReserveList.add(i, thr);thr.start();Thread.sleep(10);} catch (Exception e) {e.printStackTrace();}}for (int i = 0; i < minPools; i++) { //初始化空闲线程WorkerThread temp = new WorkerThread();m_ThreadList.add(temp); //将线程添加到线程链表中temp.start(); //启动工作线程try {Thread.sleep(10); //每个100us启动一个线程} catch (Exception e) {}}printDebugInfo();timer = new Timer(true);//启动定时器timer.schedule(new CheckThreadTask(this), 0, checkThreadPeri od); //设置定时器调度线程池}/*** 应用程序调用入口,可以是一个封装好的job类,具体视应用而定* @param work*/public synchronized void run(Object work) {synchronized (m_RunList) { //添加任务到任务链表中m_RunList.add(work);m_RunList.notify();}}/*** monitor 所要采取的动作(轮询)**/public synchronized void checkAllThreads() {//printDebugInfo();//如果空闲线程数少于预启动线程数目,并且没有达到最大的活动线程数时则增加空闲线程if(freeThreadCount<minPools && m_ThreadList.size()<maxPoo ls){int count=(minPools-freeThreadCount)>(maxActive-m_T hreadList.size())?(maxActive-m_ThreadList.size())minPools-freeThreadCount);for(int i=0;i<count;i++){Thread thr=null;try{thr=new WorkerThread();m_ThreadList.add(thr);thr.start();}catch(Exception e){e.printStackTrace();}}}if(freeThreadCount>minPools && (m_ThreadList.size()>maxActi ve) ){int count=(freeThreadCount-minPools)>(m_ThreadList.si ze()-maxActive)?(freeThreadCount-minPools)freeThreadCount-minPools);for(int i=m_ThreadList.size()-1;i>=0&&count>0;i--,coun t--){WorkerThread thr=(WorkerThread)m_ThreadList.get (i);if(thr!=null && thr.isdo){continue;}if(thr!=null){synchronized(o){m_ThreadList.remove(i);try{thr.stop(); //销毁线程}catch(Exception e){e.printStackTrace();}freeThreadCount--;}}}}for(int i=0;i<m_ThreadList.size();i++){Thread thr = (Thread)m_ThreadList.get(i);if(thr !=null && !(thr.isAlive())){try{thr.stop(); //销毁原先的线程//thr = (Thread) Class.forName((String) Ft pConfig.getProValueList("reserveList".get(i)).newInstance();thr=new WorkerThread();m_ThreadList.remove(i); //去除原先的对象m_ThreadList.set(i,thr);thr.start();}catch(Exception e){e.printStackTrace();}}}//调度保留线程//Iterator lThreadReserveIterator=m_ReserveList.iterator();for(int i=m_ReserveList.size()-1;i>=0;i--){Thread thr=(Thread)m_ReserveList.get(i);if(thr!=null && !(thr.isAlive())){//m_ReserveList.remove(i);try{//thr.destroy(); //销毁原先的线程thr.stop();thr = (Thread) Class.forName((String) FtpConfig. getProValueList("reserveList".get(i)).newInstance();m_ReserveList.remove(i); //去除原先的对象m_ReserveList.set(i,thr);thr.start();}catch(Exception e){e.printStackTrace();}}}}/*** 打印调试信息**/public void printDebugInfo() {System.out.println("m_ThreadList.size()=" + m_ThreadList.size ());System.out.println("freeThreadCount" + freeThreadCount);}/*** 获取任务链表** @return*/public LinkedList getRunList() {return m_RunList;}/*** 增加空闲线程数目**/public void addFreeThreadCount() { synchronized (o) {freeThreadCount++;}}/*** 减少空闲线程数目**/public void delFreeThreadCount() { synchronized (o) {freeThreadCount--;}}class WorkerThread extends Thread {boolean running = true;boolean isdo=false;String work;public WorkerThread() {setDaemon(false); //设置线程为精灵线程}/*** 设置线程的运行状态** @param state*/public synchronized void setRunState(boolean state) { this.running = state;}/*** 获取线程运行状态* @return*/public synchronized boolean getIsdo(){return isdo;}public void run() {while (running) {synchronized (o) {freeThreadCount++;}synchronized (m_RunList) {while (m_RunList.size() == 0) {try {m_RunList.wait();if (!running)return;} catch (InterruptedException e) {}}/* do what you want to do */synchronized (o) { //空闲线程减少freeThreadCount--;isdo=true;/*这里传进来的东西可以是一个socket句柄,用于数据的交换或者是一个其他的对象,具体业务而定*/// System.out.println(m_RunList.getFirst() + getName());BaseCtl ctl=(BaseCtl)m_RunList.getFi rst();ctl.doIt();m_RunList.removeFirst();isdo=false;}}}}}public static void main(String args[]) {ThreadPool pool = new ThreadPool();BaseCtl ctl=new LogonCtl();pool.run(ctl);}package test.threadpool;import java.util.TimerTask;;/*** @author Administrator* @version 1.0.0*/public class CheckThreadTask extends TimerTask{ Object obj=null;public CheckThreadTask(Object obj){this.obj=obj;}public void run(){((ThreadPool)obj).checkAllThreads();}}package test.threadpool;/*** @author Administrator* @version 1.0.0*/public abstract class BaseCtl { //当然通过这种方式你也可以把socket等句柄传到你的子类中来处理网络应用public abstract void doIt();}package test.threadpool;/*** @author Administrator* @version 1.0.0*/public class LogonCtl extends BaseCtl {public void doIt(){System.out.println("hello world";}}Java版线程池实现线程池调度技术原理:package test.threadpool;import java.util.*;import test.cfg.*;public class ThreadPool {private int reserve = 0; //保留线程private int minPools = 10; //最小连接池数目,预启动线程数目private int maxActive = 70; //最多活动线程数目private int maxPools = 100; //最大连接池数目private int checkThreadPeriod = 5; //检查连接池的周期ArrayList m_ThreadList; //工作线程列表ArrayList m_ReserveList; //保留线程链表LinkedList m_RunList = null; //工作任务列表int freeThreadCount = 0;//未被使用的线程数目private java.util.Timer timer = null;//定时器static Object o = new Object();public void setMinPools(int minPools) {this.minPools = minPools;}public void setMaxPools(int maxPools) {this.maxPools = maxPools;}public void setCheckThreadPeriod(int checkThreadPeriod) {this.checkThreadPeriod = checkThreadPeriod;}/*** 初始化线程池,由于各个线程启动的时候是有一定的时间间隔,启动的时候会有一定的时间**/public ThreadPool() {// reserve = Integer.parseInt(FtpConfig.getValue("reserve "); //从配置文件中获取参数// minPools = Integer.parseInt(FtpConfig.getValue("minPools "); //从配置文件中获取参数//maxActive = Integer.parseInt(FtpConfig.getValue("maxActive "); //从配置文件中获取参数//maxPools = Integer.parseInt(FtpConfig.getValue("maxPools "); //从配置文件中获取参数//checkThreadPeriod = Integer.parseInt(FtpConfig// .getValue("monitorPeriod") * 60 * 1000; //以分为轮询单位m_ThreadList = new ArrayList(); //初始化工作线程链表m_ReserveList = new ArrayList();m_RunList = new LinkedList(); //初始化任务列表ArrayList list = null;if (reserve > 0)list = (ArrayList) FtpConfig.getProValueList("reserveList";for (int i = 0; i < reserve; i++) { //启动保留线程,根据配置链表中的线程列表启动对应的保留线程.保存的是线程的全路径//class nametry {Thread thr = (Thread) Class.forName((String) list. get(i)).newInstance();m_ReserveList.add(i, thr);thr.start();Thread.sleep(10);} catch (Exception e) {e.printStackTrace();}}for (int i = 0; i < minPools; i++) { //初始化空闲线程WorkerThread temp = new WorkerThread();m_ThreadList.add(temp); //将线程添加到线程链表中temp.start(); //启动工作线程try {Thread.sleep(10); //每个100us启动一个线程} catch (Exception e) {}}printDebugInfo();timer = new Timer(true);//启动定时器timer.schedule(new CheckThreadTask(this), 0, checkThreadPeri od); //设置定时器调度线程池}/*** 应用程序调用入口,可以是一个封装好的job类,具体视应用而定* @param work*/public synchronized void run(Object work) {synchronized (m_RunList) { //添加任务到任务链表中m_RunList.add(work);m_RunList.notify();}}/*** monitor 所要采取的动作(轮询)**/public synchronized void checkAllThreads() {//printDebugInfo();//如果空闲线程数少于预启动线程数目,并且没有达到最大的活动线程数时则增加空闲线程if(freeThreadCount<minPools && m_ThreadList.size()<maxPoo ls){int count=(minPools-freeThreadCount)>(maxActive-m_T hreadList.size())?(maxActive-m_ThreadList.size())minPools-freeThreadCount);for(int i=0;i<count;i++){Thread thr=null;try{thr=new WorkerThread();m_ThreadList.add(thr);thr.start();}catch(Exception e){e.printStackTrace();}}}if(freeThreadCount>minPools && (m_ThreadList.size()>maxActi ve) ){int count=(freeThreadCount-minPools)>(m_ThreadList.si ze()-maxActive)?(freeThreadCount-minPools)freeThreadCount-minPools);for(int i=m_ThreadList.size()-1;i>=0&&count>0;i--,coun t--){WorkerThread thr=(WorkerThread)m_ThreadList.get (i);if(thr!=null && thr.isdo){continue;}if(thr!=null){synchronized(o){m_ThreadList.remove(i);try{thr.stop(); //销毁线程}catch(Exception e){e.printStackTrace();}freeThreadCount--;}}}}for(int i=0;i<m_ThreadList.size();i++){Thread thr = (Thread)m_ThreadList.get(i);if(thr !=null && !(thr.isAlive())){try{thr.stop(); //销毁原先的线程//thr = (Thread) Class.forName((String) Ft pConfig.getProValueList("reserveList".get(i)).newInstance();thr=new WorkerThread();m_ThreadList.remove(i); //去除原先的对象m_ThreadList.set(i,thr);thr.start();}catch(Exception e){e.printStackTrace();}}}//调度保留线程//Iterator lThreadReserveIterator=m_ReserveList.iterator();for(int i=m_ReserveList.size()-1;i>=0;i--){Thread thr=(Thread)m_ReserveList.get(i);if(thr!=null && !(thr.isAlive())){//m_ReserveList.remove(i);try{//thr.destroy(); //销毁原先的线程thr.stop();thr = (Thread) Class.forName((String) FtpConfig. getProValueList("reserveList".get(i)).newInstance();m_ReserveList.remove(i); //去除原先的对象m_ReserveList.set(i,thr);thr.start();}catch(Exception e){e.printStackTrace();}}}}/*** 打印调试信息**/public void printDebugInfo() {System.out.println("m_ThreadList.size()=" + m_ThreadList.size ());System.out.println("freeThreadCount" + freeThreadCount);}/*** 获取任务链表** @return*/public LinkedList getRunList() {return m_RunList;}/*** 增加空闲线程数目**/public void addFreeThreadCount() {synchronized (o) {freeThreadCount++;}}/*** 减少空闲线程数目**/public void delFreeThreadCount() {synchronized (o) {freeThreadCount--;}}class WorkerThread extends Thread {boolean running = true;boolean isdo=false;String work;public WorkerThread() {setDaemon(false); //设置线程为精灵线程}/*** 设置线程的运行状态** @param state*/public synchronized void setRunState(boolean state) { this.running = state;}/*** 获取线程运行状态* @return*/public synchronized boolean getIsdo(){return isdo;}public void run() {while (running) {synchronized (o) {freeThreadCount++;}synchronized (m_RunList) {while (m_RunList.size() == 0) {try {m_RunList.wait();if (!running)return;} catch (InterruptedException e) {}}/* do what you want to do */synchronized (o) { //空闲线程减少freeThreadCount--;isdo=true;/*这里传进来的东西可以是一个socket句柄,用于数据的交换或者是一个其他的对象,具体业务而定*/// System.out.println(m_RunList.getFirst() + getName());BaseCtl ctl=(BaseCtl)m_RunList.getFi rst();ctl.doIt();m_RunList.removeFirst();isdo=false;}}}}}public static void main(String args[]) {ThreadPool pool = new ThreadPool();BaseCtl ctl=new LogonCtl();pool.run(ctl);}package test.threadpool;import java.util.TimerTask;;/*** @author Administrator* @version 1.0.0*/public class CheckThreadTask extends TimerTask{ Object obj=null;public CheckThreadTask(Object obj){this.obj=obj;}public void run(){((ThreadPool)obj).checkAllThreads();}}package test.threadpool;/*** @author Administrator* @version 1.0.0*/public abstract class BaseCtl { //当然通过这种方式你也可以把socket等句柄传到你的子类中来处理网络应用public abstract void doIt();}package test.threadpool;/*** @author Administrator* @version 1.0.0*/public class LogonCtl extends BaseCtl {public void doIt(){System.out.println("hello world";}}。
创建线程池的几种方法

创建线程池的几种方法《嘿,创建线程池的几种超有趣方法》嘿,朋友!今天咱来唠唠创建线程池的几种方法哈,这可都是我的独家秘籍哦!首先呢,咱得知道啥是线程池。
你就把它想象成一个超级勤劳的小团队,专门帮咱处理各种任务,而且还特别高效!第一种方法呢,就像是给这个小团队找了个厉害的领队。
咱要设置好线程池的核心参数,比如线程数量啥的。
这就好比给小团队规定好有几个干活的,不能太多也不能太少,多了容易乱套,少了又干不过来活儿。
我给你讲个奇葩经历哈,有次我就没设置好这个参数,结果弄出一堆线程来,就像一群无头苍蝇到处乱撞,那场面,简直了!然后呢,咱要把任务交给这个小团队。
就像是给他们发工单一样,告诉他们要干啥。
这一步可得仔细咯,可别把任务交代错了,不然他们干错了活儿可别怪我没提醒你哦!再来说说第二种方法,这就像给小团队升级装备一样。
咱可以根据不同的任务类型,设置不同的线程池策略。
比如说,有些任务特别紧急,那就得给它们开个快速通道,让它们优先处理。
我记得有一次,有个特别重要的任务,我就没设置好策略,结果它在那慢悠悠地排队,差点把我急死!还有一种方法也挺有意思,就好像给小团队找了几个特别厉害的专家。
就是利用一些现成的框架和库来创建线程池。
这可省了咱不少事儿呢,人家都给咱弄好了,咱直接用就行。
但是哈,这里也有个要注意的地方,就像你请专家来帮忙,也得搞清楚他们擅长啥,可别瞎用哦!总结一下哈,创建线程池就这么几步:首先找好领队,设置好参数;然后发好工单,交代任务;接着根据情况升级装备或者找专家帮忙。
哎呀,你可别小看这几步,弄好了那效率蹭蹭往上涨,弄不好可就麻烦啦!就像那句话说的,“细节决定成败”。
朋友,听我这么一说,是不是觉得创建线程池也没那么难啦?赶紧去试试吧,等你成功了,可别忘了回来跟我分享分享哦!哈哈!好啦,今天就唠到这儿,下次再给你分享别的好玩儿的。
创建线程池的四种方式

创建线程池的四种方式随着计算机技术的发展,多线程技术已经成为许多应用程序的核心。
不同类型的应用程序对任务的处理方式不同,它们的多线程技术也有所不同。
最常用的线程技术就是创建线程池。
建线程池可以有效地实现任务的并发处理,有效地提高程序的执行效率。
本文将介绍创建线程池的四种方式,分别是使用Executors工厂类,使用ThreadPoolExecutor类,使用CompletionService类和使用ForkJoinPool类,并且介绍每种方式的使用步骤和优缺点。
(正文)1、使用Executors工厂类Executors工厂类是Java提供的用于创建线程池的一种工厂方法,它可以根据不同的参数返回不同类型的线程池。
Executors工厂类提供三种创建线程池的方法,分别是newFixedThreadPool、newSingleThreadExecutor、newCachedThreadPool,它们都可以通过实现Runnable接口或者Callable接口来实现任务的异步执行。
(newFixedThreadPool)newFixedThreadPool是Executors工厂类提供的一种创建线程池的方式,它可以创建固定数量的线程,每个线程可以执行实现了Runnable或者Callable接口的任务,用户可以指定线程池的大小,当一个任务提交到线程池时,线程池中有一个空闲线程存在的话,任务就会被指派给这个空闲线程,如果所有的线程都被占用,任务就会被保存在任务队列中,等待有空闲线程存在时任务就会被取出来被执行。
(newSingleThreadExecutor)newSingleThreadExecutor是Executors工厂类提供的另一种创建线程池的方式,它只会创建一个线程,任务需要按照提交的顺序一个接着一个地执行,由于只有一个线程,所以它只有一个任务队列,当任务提交给线程池,任务就会被放入任务队列,等待线程处理,但任务的执行顺序不能被改变,即使任务提交的先后顺序不一致,最终任务也会按照提交的先后顺序来执行。
java实现手写一个简单版的线程池

java实现⼿写⼀个简单版的线程池有些⼈可能对线程池⽐较陌⽣,并且更不熟悉线程池的⼯作原理。
所以他们在使⽤线程的时候,多数情况下都是new Thread来实现多线程。
但是,往往良好的多线程设计⼤多都是使⽤线程池来实现的。
为什么要使⽤线程降低资源的消耗。
降低线程创建和销毁的资源消耗。
提⾼响应速度:线程的创建时间为T1,执⾏时间T2,销毁时间T3,免去T1和T3的时间提⾼线程的可管理性下图所⽰为线程池的实现原理:调⽤⽅不断向线程池中提交任务;线程池中有⼀组线程,不断地从队列中取任务,这是⼀个典型的⽣产者-消费者模型。
要实现⼀个线程池,有⼏个问题需要考虑:队列设置多长?如果是⽆界的,调⽤⽅不断往队列中⽅任务,可能导致内存耗尽。
如果是有界的,当队列满了之后,调⽤⽅如何处理?线程池中的线程个数是固定的,还是动态变化的?每次提交新任务,是放⼊队列?还是开新线程当没有任务的时候,线程是睡眠⼀⼩段时间?还是进⼊阻塞?如果进⼊阻塞,如何唤醒?针对问题4,有3种做法:不使⽤阻塞队列,只使⽤⼀般的线程安全的队列,也⽆阻塞/唤醒机制。
当队列为空时,线程池中的线程只能睡眠⼀会⼉,然后醒来去看队列中有没有新任务到来,如此不断轮询。
不使⽤阻塞队列,但在队列外部,线程池内部实现了阻塞/唤醒机制使⽤阻塞队列很显然,做法3最完善,既避免了线程池内部⾃⼰实现阻塞/唤醒机制的⿇烦,也避免了做法1的睡眠/轮询带来的资源消耗和延迟。
现在来带⼤家⼿写⼀个简单的线程池,让⼤家更加理解线程池的⼯作原理实战:⼿写简易线程池根据上图可以知道,实现线程池需要⼀个阻塞队列+存放线程的容器/*** Five在努⼒* ⾃定义线程池*/public class ThreadPool {/** 默认线程池中的线程的数量 */private static final int WORK_NUM = 5;/** 默认处理任务的数量 */private static final int TASK_NUM = 100;/** 存放任务 */private final BlockingQueue<Runnable> taskQueue;private final Set<WorkThread> workThreads;//保存线程的集合private int workNumber;//线程数量private int taskNumber;//任务数量public ThreadPool(){this(WORK_NUM , TASK_NUM);}public ThreadPool(int workNumber , int taskNumber) {if (taskNumber<=0){taskNumber = TASK_NUM;}if (workNumber<=0){workNumber = WORK_NUM;}this.taskQueue = new ArrayBlockingQueue<Runnable>(taskNumber);this.workNumber = workNumber;this.taskNumber = taskNumber;workThreads = new HashSet<>();//⼯作线程准备好了//启动⼀定数量的线程数,从队列中获取任务处理for (int i=0;i<workNumber;i++) {WorkThread workThread = new WorkThread("thead_"+i);workThread.start();workThreads.add(workThread);}}/*** 线程池执⾏任务的⽅法,其实就是往BlockingQueue中添加元素* @param task*/public void execute(Runnable task) {try {taskQueue.put(task);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/*** 销毁线程池*/public void destroy(){System.out.println("ready close pool...");for (WorkThread workThread : workThreads) {workThread.stopWorker();workThread = null;//help gc}workThreads.clear();}/** 内部类,⼯作线程的实现 */private class WorkThread extends Thread{public WorkThread(String name){super();setName(name);}@Overridepublic void run() {while (!interrupted()) {try {Runnable runnable = taskQueue.take();//获取任务if (runnable !=null) {System.out.println(getName()+" ready execute:"+runnable.toString());runnable.run();//执⾏任务}runnable = null;//help gc} catch (Exception e) {interrupt();e.printStackTrace();}}}public void stopWorker(){interrupt();}}}上⾯代码定义了默认的线程数量和默认处理任务数量,同时⽤户也可以⾃定义线程数量和处理任务数量。
JAVA实现通用线程池

public void run(); }
//PooledThread.java package polarman.threadpool;
import java.util.Collection; import java.util.Vector;
//System.out.println("重设线程数,线程数=" + threads.size()); }
public int getPoolSize(){ return threads.size();
}
protected void notifyForIdleThread(){ hasIdleThread = true;
public PooledThread(ThreadPool pool){ this.pool = pool;
}
public void putTask(ThreadTask task){ tasks.add(task);
}
public void putTasks(ThreadTask[] tasks){ for(int i=0; i<tasks.length; i++) this.tasks.add(tasks[i]);
return null; } }
public void processTask(ThreadTask task){ PooledThread th = getIdleThread(); if(th != null){ th.putTask(task); th.startTasks(); }
java线程池用法

java线程池用法Java线程池是Java中的一个重要概念,它可以帮助我们更好地管理线程,提高程序的性能和可靠性。
本文将介绍Java线程池的用法,包括线程池的创建、使用和销毁等方面。
一、线程池的创建Java线程池的创建非常简单,只需要使用ThreadPoolExecutor类即可。
ThreadPoolExecutor类是Java中的一个线程池类,它提供了一些方法来创建和管理线程池。
下面是一个简单的线程池创建示例: ```javaExecutorService executor = Executors.newFixedThreadPool(10);```上面的代码创建了一个固定大小为10的线程池。
这个线程池可以同时执行10个任务,如果有更多的任务需要执行,它们将会被放入一个队列中等待执行。
二、线程池的使用线程池的使用非常简单,只需要将任务提交给线程池即可。
下面是一个简单的线程池使用示例:```javaexecutor.submit(new Runnable() {public void run() {// 执行任务}});```上面的代码将一个Runnable对象提交给线程池,线程池会自动分配一个线程来执行这个任务。
如果线程池中没有空闲的线程,这个任务将会被放入队列中等待执行。
三、线程池的销毁线程池的销毁非常重要,如果不及时销毁线程池,会导致程序的性能和可靠性下降。
下面是一个简单的线程池销毁示例:```javaexecutor.shutdown();```上面的代码将会销毁线程池,它会等待所有任务执行完毕后再销毁线程池。
如果你想立即销毁线程池,可以使用下面的代码:```javaexecutor.shutdownNow();```上面的代码会立即销毁线程池,它会尝试中断所有正在执行的任务。
四、线程池的优点Java线程池有很多优点,下面是一些主要的优点:1. 提高程序的性能:线程池可以重复利用线程,避免了线程的创建和销毁,从而提高了程序的性能。
创建自定义线程池(最大线程数该如何设置?)

创建⾃定义线程池(最⼤线程数该如何设置?)CPU密集型 IO密集型⼀:CPU密集型: 定义:CPU密集型也是指计算密集型,⼤部分时间⽤来做计算逻辑判断等CPU动作的程序称为CPU密集型任务。
该类型的任务需要进⾏⼤量的计算,主要消耗CPU资源。
这种计算密集型任务虽然也可以⽤多任务完成,但是任务越多,花在任务切换的时间就越多,CPU执⾏任务的效率就越低,所以,要最⾼效地利⽤CPU,计算密集型任务同时进⾏的数量应当等于CPU的核⼼数。
特点: 01:CPU 使⽤率较⾼(也就是经常计算⼀些复杂的运算,逻辑处理等情况)⾮常多的情况下使⽤ 02:针对单台机器,最⼤线程数⼀般只需要设置为CPU核⼼数的线程个数就可以了 03:这⼀类型多出现在开发中的⼀些业务复杂计算和逻辑处理过程中。
代码⽰例:1package pool;23import java.util.concurrent.Executors;4import java.util.concurrent.LinkedBlockingDeque;5import java.util.concurrent.ThreadPoolExecutor;6import java.util.concurrent.TimeUnit;78public class Demo02 {9public static void main(String[] args) {10//⾃定义线程池!⼯作中只会使⽤ ThreadPoolExecutor1112/**13 * 最⼤线程该如何定义(线程池的最⼤的⼤⼩如何设置!)14 * 1、CPU 密集型,⼏核,就是⼏,可以保持CPU的效率最⾼!15*/1617//获取电脑CPU核数18 System.out.println(Runtime.getRuntime().availableProcessors()); //8核1920 ThreadPoolExecutor threadPool = new ThreadPoolExecutor(21 2, //核⼼线程池⼤⼩22 Runtime.getRuntime().availableProcessors(), //最⼤核⼼线程池⼤⼩(CPU密集型,根据CPU核数设置)23 3, //超时了没有⼈调⽤就会释放24 TimeUnit.SECONDS, //超时单位25new LinkedBlockingDeque<>(3), //阻塞队列26 Executors.defaultThreadFactory(), //线程⼯⼚,创建线程的,⼀般不⽤动27new ThreadPoolExecutor.AbortPolicy()); //银⾏满了,还有⼈进来,不处理这个⼈的,抛出异常2829try {30//最⼤承载数,Deque + Max (队列线程数+最⼤线程数)31//超出抛出 RejectedExecutionException 异常32for (int i = 1; i <= 9; i++) {33//使⽤了线程池之后,使⽤线程池来创建线程34 threadPool.execute(()->{35 System.out.println(Thread.currentThread().getName()+" ok");36 });37 }38 } catch (Exception e) {39 e.printStackTrace();40 } finally {41//线程池⽤完,程序结束,关闭线程池42 threadPool.shutdown(); //(为确保关闭,将关闭⽅法放⼊到finally中)43 }44 }45 }⼆:IO密集型: 定义:IO密集型任务指任务需要执⾏⼤量的IO操作,涉及到⽹络、磁盘IO操作,对CPU消耗较少,其消耗的主要资源为IO。
Java线程池创建的四种方式

Java线程池创建的四种⽅式闲话少叙...package com.adao.thread;import java.util.Calendar;import java.util.Date;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;public class ThreadPool {/*** 1.创建⼀个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若⽆可回收,则新建线程*/public static void cachedThreadPool() {ExecutorService cachedThreadPool = Executors.newCachedThreadPool();for (int j = 0; j < 10; j++) {for (int i = 0; i < 10; i++) {final int index = i;// try {// Thread.sleep(1000);// } catch (InterruptedException e) {// e.printStackTrace();// }cachedThreadPool.execute(new Runnable() {@Overridepublic void run() {System.out.println(index + "--" + Thread.currentThread().getId() + " name:"+ Thread.currentThread().getName());}});}}}/*** 2.创建⼀个定长线程池,可控制线程最⼤并发数,超出的线程会在队列中等待*/public static void newFixedThreadPool() {ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);for (int j = 0; j < 10; j++) {for (int i = 0; i < 10; i++) {final int index = i;fixedThreadPool.execute(new Runnable() {@Overridepublic void run() {try {System.out.println(index + "----" + Thread.currentThread().getId() + " name:"+ Thread.currentThread().getName());Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}});}}// 两种关闭⽅式// fixedThreadPool.shutdown(); //不会⽴即终⽌线程池,⽽是要等所有任务缓存队列中的任务都执⾏完后才终⽌,但再也不会接受新的任务// fixedThreadPool.shutdownNow(); //⽴即终⽌线程池,并尝试打断正在执⾏的任务,并且清空任务缓存队列,返回尚未执⾏的任务}/*** 3.创建⼀个定长线程池,⽀持定时及周期性任务执⾏*/public static void newScheduledThreadPool() {ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(50);Calendar calendar = Calendar.getInstance();calendar.set(Calendar.HOUR_OF_DAY, 10); // 时calendar.set(Calendar.MINUTE, 53);// 分calendar.set(Calendar.SECOND, 00); // 秒// 计算现在时间和计划任务执⾏时间差多久,单位毫秒Long date = calendar.getTime().getTime() - System.currentTimeMillis();////延迟3秒执⾏scheduledThreadPool.schedule(new Runnable() {@Overridepublic void run() {System.out.println("delay 3 seconds--" + new Date().toLocaleString() + " name:"+ Thread.currentThread().getName());}}, 3, TimeUnit.SECONDS);// 延迟5秒执⾏,然后每隔2秒执⾏⼀次scheduledThreadPool.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {System.out.println("延迟5秒执⾏,然后每隔2秒执⾏⼀次--" + new Date().toLocaleString() + " name:"+ Thread.currentThread().getName());}}, 5, 2, TimeUnit.SECONDS);// 定时在某⼀时刻执⾏任务,然后间隔执⾏,如果时间过了会⽴马执⾏scheduledThreadPool.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {System.out.println("定时在某⼀时刻执⾏任务,然后间隔执⾏--" + new Date().toLocaleString() + " name:"+ Thread.currentThread().getName());}}, date / 1000, 2, TimeUnit.SECONDS);}/*** 4. 创建⼀个单线程化的线程池,它只会⽤唯⼀的⼯作线程来执⾏任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执⾏ */public static void newSingleThreadExecutor() {ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();for (int i = 0; i < 10; i++) {final int index = i;singleThreadExecutor.execute(new Runnable() {@Overridepublic void run() {try {System.out.println("单线程执⾏任务。
创建自定义线程池的方法

创建自定义线程池的方法自定义线程池是在实际开发中非常常见的需求,下面列举了50种创建自定义线程池的方法,并对其进行详细描述:1. 使用 Executors.newFixedThreadPool 方法创建固定大小的线程池:通过 Executors 工具类的 newFixedThreadPool 方法可以创建固定大小的线程池,指定线程池中的线程数量并管理线程的生命周期。
2. 使用 Executors.newCachedThreadPool 方法创建缓存线程池:使用 newCachedThreadPool 方法可以创建一个根据需要自动扩展的线程池,适用于执行许多短期异步任务的应用程序。
3. 使用 Executors.newSingleThreadExecutor 方法创建单线程的线程池:通过 newSingleThreadExecutor 方法可以创建只有一个线程的线程池,用于顺序执行任务并保证任务按提交顺序执行。
4. 实现 ThreadPoolExecutor 类自定义线程池:使用 ThreadPoolExecutor 类可以自定义线程池的核心线程数、最大线程数、线程空闲时间、任务队列等参数,满足需求定制化的线程池。
5. 使用 Executors.newScheduledThreadPool 方法创建定时线程池:使用 newScheduledThreadPool 方法创建一个大小无限的线程池,适用于执行定时任务和周期性任务的场景。
6. 扩展 AbstractExecutorService 类自定义线程池:可以根据自己的需求扩展 AbstractExecutorService 类,实现自定义的线程池逻辑和任务管理。
7. 使用 ThreadPoolExecutorService 自定义线程池:创建实现了 ExecutorService 接口的自定义线程池类,通过实现接口方法来自定义线程池的行为。
8. 使用 ForkJoinPool 创建工作窃取线程池:ForkJoinPool 是 Java 中提供的用于执行分治任务的线程池,适用于大规模数据并行处理的场景。
Java之线程池简单实现

Java之线程池简单实现线程池的技术背景在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。
在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。
所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁。
如何利用已有对象来服务就是一个需要解决的关键问题,其实这就是一些"池化资源"技术产生的原因。
多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。
但如果对多线程应用不当,会增加对单个任务的处理时间。
可以举一个简单的例子:假设在一台服务器完成一项任务的时间为T◆ T1 创建线程的时间◆ T2 在线程中执行任务的时间,包括线程间同步所需时间◆ T3 线程销毁的时间显然T = T1+T2+T3。
注意这是一个极度简化的假设。
可以看出T1,T3是多线程本身的带来的开销,我们渴望减少T1,T3所用的时间,从而减少T的时间。
但一些线程的使用者并没有注意到这一点,所以在程序中频繁的创建或销毁线程,这导致T1和T3在T中占有相当比例。
显然这是突出了线程的弱点(T1,T3),而不是优点(并发性)。
线程池技术正是关注如何缩短或调整T1,T3时间的技术,从而提高服务器程序性能的。
它把T1,T3分别安排在服务器程序的启动和结束的时间段或者一些空闲的时间段,这样在服务器程序处理客户请求时,不会有T1,T3的开销了。
线程池不仅调整T1,T3产生的时间段,而且它还显著减少了创建线程的数目。
在看一个例子:假设一个服务器一天要处理50000个请求,并且每个请求需要一个单独的线程完成。
我们比较利用线程池技术和不利于线程池技术的服务器处理这些请求时所产生的线程总数。
在线程池中,线程数一般是固定的,所以产生线程总数不会超过线程池中线程的数目或者上限(以下简称线程池尺寸),而如果服务器不利用线程池来处理这些请求则线程总数为50000。
java线程池示例(自己实现的参考别人的代码)

java线程池示例(自己实现的参考别人的代码)一般一个简单线程池至少包含下列组成部分线程池管理器(ThreadPoolManager):用于创建并管理线程池工作线程(WorkThread): 线程池中线程任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行。
任务队列:用于存放没有处理的任务。
提供一种缓冲机制。
package com.yulin.threadpool;import java.util.ArrayList;import java.util.HashMap;import java.util.LinkedList;/** 线程池管理器(PoolManager):用于创建并管理线程池,采用单例模式**/public class PoolManage {public static PoolManage mPool=new PoolManage();public final int max_pool =2;public final int max_Tasks = 15;public static ArrayList<Worker> init_pools;private int GetIdleThreadPollTime=50;//获取空闲线程轮询间隔时间,可配置private TaskMonitorThread mainThread;//任务监测线程static {init_pools = new ArrayList(1);}public static PoolManage getInstance() {if (mPool == null) {mPool = new PoolManage();}return mPool;}//获取空闲线程public Worker getIdleThread(){Worker working =null;while(true){synchronized(init_pools){for (int i = 0; i < max_pool; i++) {//Worker working = init_pools.get(i);working = init_pools.get(i);if (!working.isrunning) {// System.out.println("工作将由闲置线程" + working.getThreadTag() + "执行");return working;}}}try {Thread.sleep(5000);//放弃CPU,若干时间后重新获取空闲线程} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void init() {System.out.println("线程池初始化开始。
java threadpoolexecutor用法 -回复

java threadpoolexecutor用法-回复Java ThreadPoolExecutor用法介绍:Java ThreadPoolExecutor是Java语言提供的用于管理和调度线程池的类。
它提供了一种方便的方式来处理异步任务,实现线程的复用以及控制线程池中的线程数量。
本文将详细介绍ThreadPoolExecutor的用法,包括创建线程池、添加任务、设置参数以及监控线程池的状态等。
一、创建线程池:在使用ThreadPoolExecutor之前,需要先创建一个线程池。
创建线程池的方式有两种:一种是直接创建ThreadPoolExecutor实例,另一种是使用Executors工具类提供的静态方法来创建不同类型的线程池。
1. 直接创建ThreadPoolExecutor实例:ThreadPoolExecutor线程池构造函数的参数包括:- corePoolSize:核心线程池大小,即线程池中保持的最小线程数。
- maximumPoolSize:线程池允许创建的最大线程数。
- keepAliveTime:线程池中超过核心线程数的空闲线程的存活时间。
- unit:keepAliveTime的时间单位。
- workQueue:用于保存等待执行的任务的阻塞队列。
- threadFactory:线程工厂,用于创建新线程。
- handler:当线程池的任务队列已满且线程池中的线程数达到最大线程数时的拒绝策略。
以下是一个创建线程池的示例代码:ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue,threadFactory,handler);2. 使用Executors工具类创建线程池:Executors类提供了一些静态方法,用于创建不同类型的线程池。
Java之线程池简单实现-推荐下载

7.
8. private ThreadPoolManager(){
9.
this(5);
10.
}
11.
private ThreadPoolManager(int num){
12.
worker_num = num;
13.
workQueue = new WorkThread[worker_num];
14.
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术通关,1系电过,力管根保线据护敷生高设产中技工资术艺料0不高试仅中卷可资配以料置解试技决卷术吊要是顶求指层,机配对组置电在不气进规设行范备继高进电中行保资空护料载高试与中卷带资问负料题荷试2下卷2,高总而中体且资配可料置保试时障卷,各调需类控要管试在路验最习;大题对限到设度位备内。进来在行确管调保路整机敷使组设其高过在中程正资1常料中工试,况卷要下安加与全强过,看度并22工且22作尽22下可22都能22可地护以缩1关正小于常故管工障路作高高;中中对资资于料料继试试电卷卷保破连护坏接进范管行围口整,处核或理对者高定对中值某资,些料审异试核常卷与高弯校中扁对资度图料固纸试定,卷盒编工位写况置复进.杂行保设自护备动层与处防装理腐置,跨高尤接中其地资要线料避弯试免曲卷错半调误径试高标方中高案资等,料,编试要5写、卷求重电保技要气护术设设装交备备置底4高调、动。中试电作管资高气,线料中课并敷3试资件且、设卷料中拒管技试试调绝路术验卷试动敷中方技作设包案术,技含以来术线及避槽系免、统不管启必架动要等方高多案中项;资方对料式整试,套卷为启突解动然决过停高程机中中。语高因文中此电资,气料电课试力件卷高中电中管气资壁设料薄备试、进卷接行保口调护不试装严工置等作调问并试题且技,进术合行,理过要利关求用运电管行力线高保敷中护设资装技料置术试做。卷到线技准缆术确敷指灵设导活原。。则对对:于于在调差分试动线过保盒程护处中装,高置当中高不资中同料资电试料压卷试回技卷路术调交问试叉题技时,术,作是应为指采调发用试电金人机属员一隔,变板需压进要器行在组隔事在开前发处掌生理握内;图部同纸故一资障线料时槽、,内设需,备要强制进电造行回厂外路家部须出电同具源时高高切中中断资资习料料题试试电卷卷源试切,验除线报从缆告而敷与采设相用完关高毕技中,术资要资料进料试行,卷检并主查且要和了保检解护测现装处场置理设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。
Java线程池的配置

Java线程池的配置1、ThreadPoolExecutor的重要参数1、corePoolSize:核⼼线程数* 核⼼线程会⼀直存活,及时没有任务需要执⾏* 当线程数⼩于核⼼线程数时,即使有线程空闲,线程池也会优先创建新线程处理* 设置allowCoreThreadTimeout=true(默认false)时,核⼼线程会超时关闭2、queueCapacity:任务队列容量(阻塞队列)* 当核⼼线程数达到最⼤时,新任务会放在队列中排队等待执⾏3、maxPoolSize:最⼤线程数* 当线程数>=corePoolSize,且任务队列已满时。
线程池会创建新线程来处理任务* 当线程数=maxPoolSize,且任务队列已满时,线程池会拒绝处理任务⽽抛出异常4、 keepAliveTime:线程空闲时间* 当线程空闲时间达到keepAliveTime时,线程会退出,直到线程数量=corePoolSize* 如果allowCoreThreadTimeout=true,则会直到线程数量=05、allowCoreThreadTimeout:允许核⼼线程超时6、rejectedExecutionHandler:任务拒绝处理器* 两种情况会拒绝处理任务:- 当线程数已经达到maxPoolSize,切队列已满,会拒绝新任务- 当线程池被调⽤shutdown()后,会等待线程池⾥的任务执⾏完毕,再shutdown。
如果在调⽤shutdown()和线程池真正shutdown之间提交任务,会拒绝新任务* 线程池会调⽤rejectedExecutionHandler来处理这个任务。
如果没有设置默认是AbortPolicy,会抛出异常* ThreadPoolExecutor类有⼏个内部实现类来处理这类情况:- AbortPolicy 丢弃任务,抛运⾏时异常- CallerRunsPolicy 执⾏任务- DiscardPolicy 忽视,什么都不会发⽣- DiscardOldestPolicy 从队列中踢出最先进⼊队列(最后⼀个执⾏)的任务* 实现RejectedExecutionHandler接⼝,可⾃定义处理器2、线程池队列的选择wordQueue任务队列,⽤于转移和阻塞提交了的任务,即任务队列是运⾏线程的,任务队列根据corePoolSize和maximumPoolSize⼯作:1.当正在运⾏的线程⼩于corePoolSize,线程池会创建新的线程2.当⼤于corePoolSize⽽任务队列未满时,就会将整个任务塞⼊队列3.当⼤于corePoolSize⽽且任务队列满时,并且⼩于maximumPoolSize时,就会创建新额线程执⾏任务4、当⼤于maximumPoolSize时,会根据handler策略处理线程任务队列有以下三种模式:1. 直接提交。
java开发手册 线程池创建方式

《Java开发手册:线程池创建方式详解》一、前言在Java开发中,线程池是非常常用的一个概念。
它可以有效地管理线程的创建和销毁,提高程序的性能和稳定性。
了解线程池的创建方式对于Java开发人员来说至关重要。
本文将从线程池的基本概念出发,深入探讨不同的线程池创建方式,帮助读者全面地、深入地理解这一主题。
二、线程池的基本概念在介绍线程池的创建方式之前,我们首先来了解一下线程池的基本概念。
线程池是一种管理和重复利用线程的机制,它可以避免重复创建和销毁线程所带来的性能开销。
通过线程池,可以有效地控制并发线程的数量,防止系统资源被耗尽。
三、线程池的创建方式1. ```java开发手册```《Java开发手册》中对线程池的创建方式做了详细的规定,其中主要包括以下几种方式:1.1 直接创建ThreadPoolExecutor。
1.2 使用Executors工具类创建线程池。
1.3 通过Spring框架配置线程池。
1.4 使用ThreadPoolTaskExecutor。
1.5 自定义线程池。
2. 线程池创建方式的详细讨论2.1 直接创建ThreadPoolExecutor直接创建ThreadPoolExecutor是一种比较底层的方式,需要自行指定线程池的各项参数,包括核心线程数、最大线程数、线程存活时间等。
这种方式提供了最大的灵活性,适合对线程池有较为深入了解的开发人员。
2.2 使用Executors工具类创建线程池Executors工具类提供了一系列静态方法来创建不同类型的线程池,包括FixedThreadPool、CachedThreadPool、ScheduledThreadPool等。
这种方式简单便捷,适合快速创建标准的线程池。
2.3 通过Spring框架配置线程池Spring框架提供了对线程池的配置和管理,可以通过在配置文件中定义ThreadPoolTaskExecutor bean来实现线程池的创建和管理。
Java线程池代码实现

Java线程池代码实现线程池⼯作流程: 核⼼线程数(corePoolSize) :核⼼线程数的设计需要依据任务的处理时间和每秒产⽣的任务数量来确定,例如:执⾏⼀个任务需要0.1秒,系统百分之80的时间每秒都会产⽣100个任务,那么要想在1秒内处理完这100个任务,就需要10个线程,此时我们就可以设计核⼼线程数为10;当然实际情况不可能这么平均,所以我们⼀般按照8020原则设计即可,既按照百分之80的情况设计核⼼线程数,剩下的百分之20可以利⽤最⼤线程数处理。
任务队列长度(workQueue):任务队列长度⼀般设计为:核⼼线程数/单个任务执⾏时间*2即可(2表⽰最⼤等待时间为2秒);例如上⾯的场景中,核⼼线程数设计为10,单个任务执⾏时间为0.1秒,则队列长度可以设计为200。
最⼤线程数(maximumPoolSize):最⼤线程数的设计除了需要参照核⼼线程数的条件外,还需要参照系统每秒产⽣的最⼤任务数决定:例如:上述环境中,如果系统每秒最⼤产⽣的任务是1000个,那么,最⼤线程数=(最⼤任务数-任务队列长度)*单个任务执⾏时间;既: 最⼤线程数= (1000-200)*0.1=80个。
最⼤空闲时间(keepAliveTime) 这个参数的设计完全参考系统运⾏环境和硬件压⼒设定,没有固定的参考值,⽤户可以根据经验和系统产⽣任务的时间间隔合理设置⼀个值即可; 上⾯4个参数的设置只是⼀般的设计原则,并不是固定的,可以根据实际情况灵活调整!⾃定义线程池:/*需求:⾃定义线程池练习,这是任务类,需要实现Runnable;包含任务编号,每⼀个任务执⾏时间设计为0.2秒*/public class MyTask implements Runnable{private int id;//由于run⽅法是重写接⼝中的⽅法,因此id这个属性初始化可以利⽤构造⽅法完成public MyTask(int id) {this.id = id;}@Overridepublic void run() {String name = Thread.currentThread().getName();System.out.println("线程:"+name+" 即将执⾏任务:"+id);try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程:"+name+" 完成了任务:"+id);}@Overridepublic String toString() {return "MyTask{" +"id=" + id +'}';}}/*需求:编写⼀个线程类,需要继承Thread类,设计⼀个属性,⽤于保存线程的名字;设计⼀个集合,⽤于保存所有的任务;*/public class MyWorker extends Thread{private List<Runnable> tasks;//利⽤构造⽅法,给成员变量赋值public MyWorker(String name, List<Runnable> tasks) {super(name);this.tasks = tasks;}@Overridepublic void run() {//判断集合中是否有任务,只要有,就⼀直执⾏任务while (tasks.size()>0){Runnable r = tasks.remove(0);r.run();}}}/*这是⾃定义的线程池类;成员变量:1:任务队列集合需要控制线程安全问题2:当前线程数量3:核⼼线程数量4:最⼤线程数量5:任务队列的长度成员⽅法1:提交任务;将任务添加到集合中,需要判断是否超出了任务总长度2:执⾏任务;判断当前线程的数量,决定创建核⼼线程还是⾮核⼼线程*/public class MyThreadPool {// 1:任务队列集合需要控制线程安全问题private List<Runnable> tasks = Collections.synchronizedList(new LinkedList<>()); //2:当前线程数量private int num;//3:核⼼线程数量private int corePoolSize;//4:最⼤线程数量private int maxSize;//5:任务队列的长度private int workSize;public MyThreadPool(int corePoolSize, int maxSize, int workSize) {this.corePoolSize = corePoolSize;this.maxSize = maxSize;this.workSize = workSize;}//1:提交任务;public void submit(Runnable r){//判断当前集合中任务的数量,是否超出了最⼤任务数量if(tasks.size() >= workSize){System.out.println("任务:"+r+"被丢弃了...");}else {tasks.add(r);//执⾏任务execTask(r);}}//2:执⾏任务;private void execTask(Runnable r) {//判断当前线程池中的线程总数量,是否超出了核⼼数,if(num < corePoolSize){new MyWorker("核⼼线程:"+num,tasks).start();num++;}else if(num < maxSize){new MyWorker("⾮核⼼线程:"+num,tasks).start();num++;}else {System.out.println("任务:"+r+" 被缓存了...");}}}/*测试类:1: 创建线程池类对象;2: 提交多个任务*/public class MyTest {public static void main(String[] args) {//1:创建线程池类对象;MyThreadPool pool = new MyThreadPool(2,4,20);//2: 提交多个任务for (int i = 0; i <30 ; i++) {//3:创建任务对象,并提交给线程池MyTask my = new MyTask(i);pool.submit(my);}}}Java内置线程池:package com.fgy.demo07;public class RunnableImpl implements Runnable {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "创建了⼀个新的线程");}}package com.fgy.demo07;public class ExtendsThread extends Thread {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "创建了⼀个新的线程");}}package com.fgy.demo07;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class Demo01ThreadTool {public static void main(String[] args) {ExecutorService pool = Executors.newFixedThreadPool(3); // 创建线程池,初始化有三个线程 pool.submit(new RunnableImpl());pool.submit(new Runnable(){@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "创建了⼀个新的线程"); }});pool.submit(new Thread(){@Overridepublic void run() {System.out.println(getName() + "创建了⼀个新的线程");}});pool.submit(new ExtendsThread()); // pool-1-thread-2创建了⼀个新的线程// Thread-0创建了⼀个新的线程// pool-1-thread-3创建了⼀个新的线程// pool-1-thread-1创建了⼀个新的线程// 销毁线程池pool.shutdown();}}。
Java简单实现线程池

Java简单实现线程池本⽂实例为⼤家分享了Java简单实现线程池的具体代码,供⼤家参考,具体内容如下⼀、线程池线程池是⼀种缓冲提⾼效率的技术。
相当于⼀个池⼦,⾥⾯存放⼤量已经创建好的线程,当有⼀个任务需要处理时,可以直接从池⼦⾥⾯取⼀个线程去执⾏它。
包括内存池,很多缓冲的技术都是采⽤这种技术。
其实理解起来很简答!为什么需要线程池,这种池的技术?1.1 减少开辟资源和销毁资源带来的损耗。
开辟线程,申请内存(具体的可以看C语⾔中malloc底层实现原理),销毁线程、释放内存资源等⼀些操作都是有时间消耗的。
因此⼀开始开辟⼤量的资源进⾏管理,需要使⽤时从池中取⼀个去使⽤,使⽤完毕后再放回池中管理,这样可以避免资源开辟和销毁带来的时间损耗。
1.2 提⾼响应。
⽤户来了⼀个请求,能够⽴刻从开辟好的线程池中取⼀个线程去处理执⾏。
提⾼响应效率,提⾼⽤户体验。
1.3 有效管理资源管理资源统⼀开辟和销毁,监控线程状态和调优⼆、线程池分析对于线程池的实现我们划分为2个部分1、线程安全的任务队列(采⽤队列,不过是线程安全的⽽已),保证⼯作线程在去任务时不会发⽣冲突(重复取同⼀个任务处理,⼆次执⾏或者多次的问题)。
2、对⼯作线程的监管(采⽤是List管理⼯作线程),⽅便线程的销毁和管理。
线程池处理逻辑:1、每当添加⼀个任务,就会从线程池中取⼀个⼯作线程去处理执⾏它。
2、没有任务处理时,⼯作线程应该处于阻塞状态等待任务到来,不会竞争占⽤CPU资源3、线程池相当于⽣产-消费模型,只不过⽣产线程的中⽣产任务不同罢了。
3、主线程相当于监管线程,最终负责⼯作线程的销毁。
三、线程池实现1、⼯作线程Worker1.1、⼯作线程负责从阻塞任务队列中取出任务执⾏。
由于存在很多个线程对同⼀个队列操作,因此这个任务队列⼀定得是线程安全的(采⽤BlockingQueue接⼝,这是GUC提供的,线程安全)1.2、⼯作线程的创建⽅式属于线程创建的⽅式之⼀。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
100行Java代码构建一个线程池本示例程序由三个类构成,第一个是TestThreadPool类,它是一个测试程序,用来模拟客户端的请求,当你运行它时,系统首先会显示线程池的初始化信息,然后提示你从键盘上输入字符串,并按下回车键,这时你会发现屏幕上显示信息,告诉你某个线程正在处理你的请求,如果你快速地输入一行行字符串,那么你会发现线程池中不断有线程被唤醒,来处理你的请求,在本例中,我创建了一个拥有10个线程的线程池,如果线程池中没有可用线程了,系统会提示你相应的警告信息,但如果你稍等片刻,那你会发现屏幕上会陆陆续续提示有线程进入了睡眠状态,这时你又可以发送新的请求了。
第二个类是ThreadPoolManager类,顾名思义,它是一个用于管理线程池的类,它的主要职责是初始化线程池,并为客户端的请求分配不同的线程来进行处理,如果线程池满了,它会对你发出警告信息。
最后一个类是SimpleThread类,它是Thread类的一个子类,它才真正对客户端的请求进行处理,SimpleThread在示例程序初始化时都处于睡眠状态,但如果它接受到了ThreadPoolManager类发过来的调度信息,则会将自己唤醒,并对请求进行处理。
首先我们来看一下TestThreadPool类的源码://TestThreadPool.java1 import java.io.*;234 public class TestThreadPool5 {6 public static void main(String[] args)7 {8 try{9 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));10 String s;11 ThreadPoolManager manager = new ThreadPoolManager(10);12 while((s = br.readLine()) != null)13 {14 manager.process(s);15 }16 }catch(IOException e){}17 }18 }由于此测试程序用到了输入输入类,因此第1行导入了JAVA的基本IO处理包,在第11行中,我们创建了一个名为manager的类,它给ThreadPoolManager类的构造函数传递了一个值为10的参数,告诉ThreadPoolManager类:我要一个有10个线程的池,给我创建一个吧!第12行至15行是一个无限循环,它用来等待用户的键入,并将键入的字符串保存在s变量中,并调用ThreadPoolManager类的process 方法来将这个请求进行处理。
下面我们再进一步跟踪到ThreadPoolManager类中去,以下是它的源代码://ThreadPoolManager.java1 import java.util.*;234 class ThreadPoolManager5 {67 private int maxThread;8 public Vector vector;9 public void setMaxThread(int threadCount)10 {11 maxThread = threadCount;12 }1314 public ThreadPoolManager(int threadCount)15 {16 setMaxThread(threadCount);17 System.out.println("Starting thread pool...");18 vector = new Vector();19 for(int i = 1; i <= 10; i++)20 {21 SimpleThread thread = new SimpleThread(i);22 vector.addElement(thread);23 thread.start();24 }25 }2627 public void process(String argument)28 {29 int i;30 for(i = 0; i < vector.size(); i++)31 {32 SimpleThread currentThread = (SimpleThread)vector.elementAt(i);33 if(!currentThread.isRunning())34 {35 System.out.println("Thread "+ (i+1) +" is processing:" +argument);36 currentThread.setArgument(argument);37 currentThread.setRunning(true);38 return;39 }40 }41 if(i == vector.size())42 {43 System.out.println("pool is full, try in another time.");44 }45 }46 }//end of class ThreadPoolManager我们先关注一下这个类的构造函数,然后再看它的process()方法。
第16-24行是它的构造函数,首先它给ThreadPoolManager类的成员变量maxThread赋值,maxThread表示用于控制线程池中最大线程的数量。
第18行初始化一个数组vector,它用来存放所有的SimpleThread类,这时候就充分体现了JAVA语言的优越性与艺术性:如果你用C语言的话,至少要写100行以上的代码来完成vector的功能,而且C语言数组只能容纳类型统一的基本数据类型,无法容纳对象。
好了,闲话少说,第19-24行的循环完成这样一个功能:先创建一个新的SimpleThread 类,然后将它放入vector中去,最后用thread.start()来启动这个线程,为什么要用start()方法来启动线程呢?因为这是JAVA语言中所规定的,如果你不用的话,那这些线程将永远得不到激活,从而导致本示例程序根本无法运行。
下面我们再来看一下process()方法,第30-40行的循环依次从vector数组中选取SimpleThread线程,并检查它是否处于激活状态(所谓激活状态是指此线程是否正在处理客户端的请求),如果处于激活状态的话,那继续查找vector数组的下一项,如果vector数组中所有的线程都处于激活状态的话,那它会打印出一条信息,提示用户稍候再试。
相反如果找到了一个睡眠线程的话,那第35-38行会对此进行处理,它先告诉客户端是哪一个线程来处理这个请求,然后将客户端的请求,即字符串argument转发给SimpleThread类的setArgument()方法进行处理,并调用SimpleThread类的setRunning()方法来唤醒当前线程,来对客户端请求进行处理。
可能你还对setRunning()方法是怎样唤醒线程的有些不明白,那我们现在就进入最后一个类:SimpleThread类,它的源代码如下://SimpleThread.java1 class SimpleThread extends Thread2 {3 private boolean runningFlag;4 private String argument;5 public boolean isRunning()6 {7 return runningFlag;8 }9 public synchronized void setRunning(boolean flag)10 {11 runningFlag = flag;12 if(flag)13 this.notify();14 }1516 public String getArgument()17 {18 return this.argument;19 }20 public void setArgument(String string)21 {22 argument = string;23 }2425 public SimpleThread(int threadNumber)26 {27 runningFlag = false;28 System.out.println("thread " + threadNumber + "started.");29 }3031 public synchronized void run()32 {33 try{34 while(true)35 {36 if(!runningFlag)37 {38 this.wait();39 }40 else41 {42 System.out.println("processing " + getArgument() + "... done.");43 sleep(5000);44 System.out.println("Thread is sleeping...");45 setRunning(false);46 }47 }48 } catch(InterruptedException e){49 System.out.println("Interrupt");50 }51 }//end of run()52 }//end of class SimpleThread如果你对JAVA的线程编程有些不太明白的话,那我先在这里简单地讲解一下,JAVA有一个名为Thread的类,如果你要创建一个线程,则必须要从Thread类中继承,并且还要实现Thread类的run()接口,要激活一个线程,必须调用它的start()方法,start()方法会自动调用run()接口,因此用户必须在run()接口中写入自己的应用处理逻辑。
那么我们怎么来控制线程的睡眠与唤醒呢?其实很简单,JAVA语言为所有的对象都内置了wait()和notify()方法,当一个线程调用wait()方法时,则线程进入睡眠状态,就像停在了当前代码上了,也不会继续执行它以下的代码了,当调用notify()方法时,则会从调用wait()方法的那行代码继续执行以下的代码,这个过程有点像编译器中的断点调试的概念。
以本程序为例,第38行调用了wait()方法,则这个线程就像凝固了一样停在了38行上了,如果我们在第13行进行一个notify()调用的话,那线程会从第38行上唤醒,继续从第39行开始执行以下的代码了。