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. 提高程序的性能:线程池可以重复利用线程,避免了线程的创建和销毁,从而提高了程序的性能。
- 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行开始执行以下的代码了。