导航:首页 > 编程语言 > java线程池处理

java线程池处理

发布时间:2023-08-18 23:50:53

java线程池怎么实现的

线程池简介:

多线程技术主要解决处理器单元内多个线程执行的问题,它可以显着减少处理器单元的闲置时间,增加处理器单元的吞吐能力。


假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。

如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能。

一个线程池包括以下四个基本组成部分:

1、线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;

2、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;

3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;

4、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。

线程池技术正是关注如何缩短或调整T1,T3时间的技术,从而提高服务器程序性能的。它把T1,T3分别安排在服务器程序的启动和结束的时间段或者一些空闲的时间段,这样在服务器程序处理客户请求时,不会有T1,T3的开销了。

线程池不仅调整T1,T3产生的时间段,而且它还显着减少了创建线程的数目,看一个例子:

假设一个服务器一天要处理50000个请求,并且每个请求需要一个单独的线程完成。在线程池中,线程数一般是固定的,所以产生线程总数不会超过线程池中线程的数目,而如果服务器不利用线程池来处理这些请求则线程总数为50000。一般线程池大小是远小于50000。所以利用线程池的服务器程序不会为了创建50000而在处理请求时浪费时间,从而提高效率。

代码实现中并没有实现任务接口,而是把Runnable对象加入到线程池管理器(ThreadPool),然后剩下的事情就由线程池管理器(ThreadPool)来完成了

packagemine.util.thread;

importjava.util.LinkedList;
importjava.util.List;

/**
*线程池类,线程管理器:创建线程,执行任务,销毁线程,获取线程基本信息
*/
publicfinalclassThreadPool{
//线程池中默认线程的个数为5
privatestaticintworker_num=5;
//工作线程
privateWorkThread[]workThrads;
//未处理的任务
_task=0;
//任务队列,作为一个缓冲,List线程不安全
privateList<Runnable>taskQueue=newLinkedList<Runnable>();
;

//创建具有默认线程个数的线程池
privateThreadPool(){
this(5);
}

//创建线程池,worker_num为线程池中工作线程的个数
privateThreadPool(intworker_num){
ThreadPool.worker_num=worker_num;
workThrads=newWorkThread[worker_num];
for(inti=0;i<worker_num;i++){
workThrads[i]=newWorkThread();
workThrads[i].start();//开启线程池中的线程
}
}

//单态模式,获得一个默认线程个数的线程池
(){
returngetThreadPool(ThreadPool.worker_num);
}

//单态模式,获得一个指定线程个数的线程池,worker_num(>0)为线程池中工作线程的个数
//worker_num<=0创建默认的工作线程个数
(intworker_num1){
if(worker_num1<=0)
worker_num1=ThreadPool.worker_num;
if(threadPool==null)
threadPool=newThreadPool(worker_num1);
returnthreadPool;
}

//执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定
publicvoidexecute(Runnabletask){
synchronized(taskQueue){
taskQueue.add(task);
taskQueue.notify();
}
}

//批量执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定
publicvoidexecute(Runnable[]task){
synchronized(taskQueue){
for(Runnablet:task)
taskQueue.add(t);
taskQueue.notify();
}
}

//批量执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定
publicvoidexecute(List<Runnable>task){
synchronized(taskQueue){
for(Runnablet:task)
taskQueue.add(t);
taskQueue.notify();
}
}

//销毁线程池,该方法保证在所有任务都完成的情况下才销毁所有线程,否则等待任务完成才销毁
publicvoiddestroy(){
while(!taskQueue.isEmpty()){//如果还有任务没执行完成,就先睡会吧
try{
Thread.sleep(10);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
//工作线程停止工作,且置为null
for(inti=0;i<worker_num;i++){
workThrads[i].stopWorker();
workThrads[i]=null;
}
threadPool=null;
taskQueue.clear();//清空任务队列
}

//返回工作线程的个数
publicintgetWorkThreadNumber(){
returnworker_num;
}

//返回已完成任务的个数,这里的已完成是只出了任务队列的任务个数,可能该任务并没有实际执行完成
(){
returnfinished_task;
}

//返回任务队列的长度,即还没处理的任务个数
publicintgetWaitTasknumber(){
returntaskQueue.size();
}

//覆盖toString方法,返回线程池信息:工作线程个数和已完成任务个数
@Override
publicStringtoString(){
return"WorkThreadnumber:"+worker_num+"finishedtasknumber:"
+finished_task+"waittasknumber:"+getWaitTasknumber();
}

/**
*内部类,工作线程
*/
{
//该工作线程是否有效,用于结束该工作线程
privatebooleanisRunning=true;

/*
*关键所在啊,如果任务队列不空,则取出任务执行,若任务队列空,则等待
*/
@Override
publicvoidrun(){
Runnabler=null;
while(isRunning){//注意,若线程无效则自然结束run方法,该线程就没用了
synchronized(taskQueue){
while(isRunning&&taskQueue.isEmpty()){//队列为空
try{
taskQueue.wait(20);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
if(!taskQueue.isEmpty())
r=taskQueue.remove(0);//取出任务
}
if(r!=null){
r.run();//执行任务
}
finished_task++;
r=null;
}
}

//停止工作,让该线程自然执行完run方法,自然结束
publicvoidstopWorker(){
isRunning=false;
}
}
}

❷ java线程池(一) 简述线程池的几种使用方式

首先说明下java线程是如何实现线程重用的
1. 线程执行完一个Runnable的run()方法后,不会被杀死
2. 当线程被重用时,这个线程会进入新Runnable对象的run()方法12

java线程池由Executors提供的几种静态方法创建线程池。下面通过代码片段简单介绍下线程池的几种实现方式。后续会针对每个实现方式做详细的说明
newFixedThreadPool
创建一个固定大小的线程池
添加的任务达到线程池的容量之后开始加入任务队列开始线程重用总共开启线程个数跟指定容量相同。
@Test
public void newFixedThreadPool() throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService = Executors.newFixedThreadPool(1, new ThreadFactoryBuilder().build());
RunThread run1 = new RunThread("run 1");
executorService.execute(run1);
executorService.shutdown();
}12345678

newSingleThreadExecutor
仅支持单线程顺序处理任务
@Test
public void newSingleThreadExecutor() throws Exception {
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().build());
executorService.execute(new RunThread("run 1"));
executorService.execute(new RunThread("run 2"));
executorService.shutdown();

}123456789

newCachedThreadPool
这种情况跟第一种的方式类似,不同的是这种情况线程池容量上线是Integer.MAX_VALUE 并且线程池开启缓存60s
@Test
public void newCachedThreadPool() throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool();
executorService = Executors.newCachedThreadPool(new ThreadFactoryBuilder().build());
executorService.execute(new RunThread("run 1"));
executorService.execute(new RunThread("run 2"));
executorService.shutdown();

}123456789

newWorkStealingPool
支持给定的并行级别,并且可以使用多个队列来减少争用。
@Test
public void newWorkStealingPool() throws Exception {
ExecutorService executorService = Executors.newWorkStealingPool();
executorService = Executors.newWorkStealingPool(1);
RunThread run1 = new RunThread("run 1");
executorService.execute(run1);
executorService.shutdown();

}123456789

newScheledThreadPool
看到的现象和第一种相同,也是在线程池满之前是新建线程,然后开始进入任务队列,进行线程重用
支持定时周期执行任务(还没有看完)
@Test
public void newScheledThreadPool() throws Exception {
ExecutorService executorService = Executors.newScheledThreadPool(1);
executorService = Executors.newScheledThreadPool(1, new ThreadFactoryBuilder().build());
executorService.execute(new RunThread("run 1"));
executorService.execute(new RunThread("run 2"));
executorService.shutdown();

}

❸ 什么是java线程池

多线程是为了能够让计算机资源合理的分配,对于处理不同的任务创建不同的线程进行处理,但是计算机创建一个线程或者销毁一个线程所花费的也是比较昂贵的,有时候需要同时处理的事情比较多,就需要我们频繁的进行线程的创建和销毁,这样花费的时间也是比较多的。为了解决这一问题,我们就可以引用线程池的概念。
所谓线程池就是将线程集中管理起来,当需要线程的时候,可以从线程池中获取空闲的线程,这样可以减少线程的频繁创建与销毁,节省很大的时间和减少很多不必要的操作。
在java中提供了ThreadPoolExecutor类来进行线程的管理,这个类继承于AbstractExecutorService,而AbstractExecutorService实现了ExecutorService接口,我们可以使用ThreadPoolExecutor来进行线程池的创建。
在ThreadPoolExecutor的构造方法中,有多个参数,可以配置不同的参数来进行优化。这个类的源码构造方法为:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)其中每个参数代表的意义分别为
corePoolSize : 线程池中的核心线程数量,当线程池中当前的线程数小于这个配置的时候,如果有一个新的任务到来,即使线程池中还存在空闲状态的线程,程序也会继续创建一个新的线程放进线程池当中
maximumPoolSize: 线程池中的线程最大数量
keepAliveTime:当线程池中的线程数量大于配置的核心线程数量(corePoolSize)的时候,如果当前有空闲的线程,则当这个空闲线程可以存在的时间,如果在keepAliveTime这个时间点内没有新的任务使用这个线程,那么这个线程将会结束,核心线程不会结束,但是如果配置了allowCoreThreadTimeOut = true,则当空闲时间超过keepAliveTime之后,线程也会被结束调,默认allowCoreThreadTimeOut = false,即表示默认情况下,核心线程会一直存在于线程池当中。
unit : 空闲线程保持连接时间(keepAliveTime)的时间单位
workQueue:阻塞的任务队列,用来保存等待需要执行的任务。
threadFactory :线程工厂,可以根据自己的需求去创建线程的对象,设置线程的名称,优先级等属性信息。
handler:当线程池中存在的线程数超过设置的最大值之后,新的任务就会被拒绝,可以自己定义一个拒绝的策略,当新任务被拒绝之后,就会使用hander方法进行处理。
在java中也提供了Executors工具类,在这个工具类中提供了多个创建线程池的静态方法,其中包含newCachedThreadPool、newFixedThreadPool、newScheledThreadPool、newSingleThreadExecutor等。但是他们每个方法都是创建了ThreadPoolExecutor对象,不同的是,每个对象的初始 参数值不一样;

❹ 【Java基础】线程池的原理是什么

什么是线程池?

总归为:池化技术 ---》数据库连接池 缓存架构 缓存池 线程池 内存池,连接池,这种思想演变成缓存架构技术---> JDK设计思想有千丝万缕的联系

首先我们从最核心的ThreadPoolExecutor类中的方法讲起,然后再讲述它的实现原理,接着给出了它的使用示例,最后讨论了一下如何合理配置线程池的大小。

Java 中的 ThreadPoolExecutor 类

java.uitl.concurrent.ThreadPoolExecutor 类是线程池中最核心的一个类,因此如果要透彻地了解Java 中的线程池,必须先了解这个类。下面我们来看一下 ThreadPoolExecutor 类的具体实现源码。

在 ThreadPoolExecutor 类中提供了四个构造方法:

❺ java常用的几种线程池实例讲解

下面给你介绍4种线程池:

1、newCachedThreadPool:

2、newFixedThreadPool:


3、newSingleThreadExecutor

4、NewScheledThreadPool:

最后给你说一下线程池任务执行流程:

❻ Java 线程池的问题

你的理解没毛病。

核心线程数(corePoolSize):核心线程会一直存活,即使没有任务需要处理。当线程数小于核心线程数时,即使现有的线程空闲,线程池也蠢答会优先创建新线程来处理任务,而不是直接交给现有的线程处理。

最大线程数(maxPoolSize):当线程数大于或等于核心线程,且任务队列已满时,线改丛程池会创建新的线程,直到线程数量达到maxPoolSize。如果线程数已等于maxPoolSize,且任务队列已满,则已超出线程池的处理能力,线程池会拒绝处理任务而抛出异常。

线程池按以下行为执行任务

❼ Java线程:新特征-线程池

Sun在Java 中 对Java线程的类库做了大量的扩展 其中线程池就是Java 的新特征之一 除了线程池之外 还有很多多线程相关的内容 为多线程的编程带来了极大便利 为了编写高效稳定可靠的多线程程序 线程部分的新增内容显得尤为重要 有关Java 线程新特征的内容全部在ncurrent下面 里面包含数目众多的接口和类 熟悉这部羡盯带分API特征是一项艰难的学习过程 目前有关这方面的资料和书籍都少之又少 大所属介绍线程方面书籍还停留在java 之前的知识层面上 当然新特征对做多线程程序没有必须的关系 在java 之前通用可以写出很优秀的多线程程序 只是代价不一样而已 线程池的基本思想还是一种对象池的思想 开辟一块内存空间 里面存放了众多(未死亡)的线程 池中线程执行调度由池管理器来处理 当有线程任务时 从池中取一个 执行完成后线程对象归池 这样可以避免反复创建线程对象所带来的性能开销 节省了系统的资源 在Java 之前 要实现一个线程池是相当有难度的 现在Java 为我们做好了一切 我们只需要按照提供的API来使用 即可享受线程池带来的极大便利 则蚂 Java 的线程池分好多种 固定尺寸的线程池 可变尺寸连接池 在使用线程池之前 必须知道如何去创建一个线程池 在Java 中 需要了解的是ncurrent Executors类的API 这个类提供大量创建连接池的静态方法 是必须掌握的 一 固定大小的线程池 import ncurrent Executors; import ncurrent ExecutorService; /** * Java线程 线程池 * * @author Administrator : : */ public class Test { public static void main(String[] args) { //创建一个可重用固定线程数的线程池 ExecutorService pool = Executors newFixedThreadPool( ); //创建实现了Runnable接口对象 Thread对象当然也实现了Runnable接口 Thread t = new MyThread(); Thread t = new MyThread(); Thread t = new MyThread(); 兄芦Thread t = new MyThread(); Thread t = new MyThread(); //将线程放入池中进行执行 pool execute(t ); pool execute(t ); pool execute(t ); pool execute(t ); pool execute(t ); //关闭线程池 pool shutdown(); } } class MyThread extends Thread{ @Override public void run() { System out println(Thread currentThread() getName()+ 正在执行 ); } } pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 Process finished with exit code 二 单任务线程池 在上例的基础上改一行创建pool对象的代码为 //创建一个使用单个 worker 线程的 Executor 以无界队列方式来运行该线程 ExecutorService pool = Executors newSingleThreadExecutor(); 输出结果为 pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 Process finished with exit code 对于以上两种连接池 大小都是固定的 当要加入的池的线程(或者任务)超过池最大尺寸时候 则入此线程池需要排队等待 一旦池中有线程完毕 则排队等待的某个线程会入池执行

三 可变尺寸的线程池 与上面的类似 只是改动下pool的创建方式 //创建一个可根据需要创建新线程的线程池 但是在以前构造的线程可用时将重用它们 ExecutorService pool = Executors newCachedThreadPool(); pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 Process finished with exit code 四 延迟连接池 import ncurrent Executors; import ncurrent ScheledExecutorService; import ncurrent TimeUnit; /** * Java线程 线程池 * * @author Administrator : : */ public class Test { public static void main(String[] args) { //创建一个线程池 它可安排在给定延迟后运行命令或者定期地执行 ScheledExecutorService pool = Executors newScheledThreadPool( ); //创建实现了Runnable接口对象 Thread对象当然也实现了Runnable接口 Thread t = new MyThread(); Thread t = new MyThread(); Thread t = new MyThread(); Thread t = new MyThread(); Thread t = new MyThread(); //将线程放入池中进行执行 pool execute(t ); pool execute(t ); pool execute(t ); //使用延迟执行风格的方法 pool schele(t TimeUnit MILLISECONDS); pool schele(t TimeUnit MILLISECONDS); //关闭线程池 pool shutdown(); } } class MyThread extends Thread { @Override public void run() { System out println(Thread currentThread() getName() + 正在执行 ); } } pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 Process finished with exit code

五 单任务延迟连接池 在四代码基础上 做改动 //创建一个单线程执行程序 它可安排在给定延迟后运行命令或者定期地执行 ScheledExecutorService pool = Executors (); pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 Process finished with exit code 六 自定义线程池 import ncurrent ArrayBlockingQueue; import ncurrent BlockingQueue; import ncurrent ThreadPoolExecutor; import ncurrent TimeUnit; /** * Java线程 线程池 自定义线程池 * * @author Administrator : : */ public class Test { public static void main(String[] args) { //创建等待队列 BlockingQueue<Runnable> bqueue = new ArrayBlockingQueue<Runnable>( ); //创建一个单线程执行程序 它可安排在给定延迟后运行命令或者定期地执行 ThreadPoolExecutor pool = new ThreadPoolExecutor( TimeUnit MILLISECONDS bqueue); //创建实现了Runnable接口对象 Thread对象当然也实现了Runnable接口 Thread t = new MyThread(); Thread t = new MyThread(); Thread t = new MyThread(); Thread t = new MyThread(); Thread t = new MyThread(); Thread t = new MyThread(); Thread t = new MyThread(); //将线程放入池中进行执行 pool execute(t ); pool execute(t ); pool execute(t ); pool execute(t ); pool execute(t ); pool execute(t ); pool execute(t ); //关闭线程池 pool shutdown(); } } class MyThread extends Thread { @Override public void run() { System out println(Thread currentThread() getName() + 正在执行 ); try { Thread sleep( L); } catch (InterruptedException e) { e printStackTrace(); } } }

pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 pool thread 正在执行 Process finished with exit code 创建自定义线程池的构造方法很多 本例中参数的含义如下

ThreadPoolExecutor

用给定的初始参数和默认的线程工厂及处理程序创建新的 ThreadPoolExecutor 使用 Executors 工厂方法之一比使用此通用构造方法方便得多 参数 corePoolSize 池中所保存的线程数 包括空闲线程 maximumPoolSize 池中允许的最大线程数 keepAliveTime 当线程数大于核心时 此为终止前多余的空闲线程等待新任务的最长时间 unit keepAliveTime 参数的时间单位 workQueue 执行前用于保持任务的队列 此队列仅保持由 execute 方法提交的 Runnable 任务 抛出 IllegalArgumentException 如果 corePoolSize 或 keepAliveTime 小于零 或者 maximumPoolSize 小于或等于零 或者 corePoolSize 大于 maximumPoolSize NullPointerException 如果 workQueue 为 null 自定义连接池稍微麻烦些 不过通过创建的ThreadPoolExecutor线程池对象 可以获取到当前线程池的尺寸 正在执行任务的线程数 工作队列等等 有关Java 线程池的内容到此就没有了 更多的内容还需要研读API来获取 lishixin/Article/program/Java/hx/201311/26769

阅读全文

与java线程池处理相关的资料

热点内容
刚入行的程序员 浏览:743
mc手机版如何免费开服务器 浏览:627
加密货币延期发布 浏览:978
福昕pdf阅读器删除 浏览:436
app收集信息怎么设置 浏览:288
python少儿编程图 浏览:747
命令方块解禁 浏览:930
海康威视服务器地址和设备标识 浏览:298
做网站用php还是html 浏览:199
脸部识别算法模型厂家 浏览:176
反编译的程序带注释吗 浏览:713
安装软件服务器未响应怎么解决 浏览:531
阀门开度单片机 浏览:568
python多线程有什么坑 浏览:681
程序员从互联网跳槽到银行里 浏览:244
百度网盘资源解压后暂不支持在线 浏览:220
android自动化环境 浏览:253
androidrealm加密 浏览:513
地图正在解压缩是什么意思 浏览:217
电脑软件能放在文件夹吗 浏览:786