线程池的通俗理解
- 格式:docx
- 大小:244.69 KB
- 文档页数:2
java线程池的使用例子随着计算机技术的不断发展,我们的软件系统越来越复杂,程序的性能要求也越来越高。
在这样的背景下,线程池成为了一种非常重要的工具。
Java线程池是Java提供的一种简单易用的线程管理工具,可以帮助我们更好地管理程序中的线程,提高程序的性能和稳定性。
本文将通过一个实际的例子来介绍Java线程池的使用方法和注意事项。
希望读者可以通过本文的学习,更好地掌握Java线程池的使用技巧。
一、什么是线程池?在介绍Java线程池之前,我们需要先了解什么是线程池。
线程池是一种管理线程的机制,可以帮助我们更好地管理程序中的线程,提高程序的性能和稳定性。
线程池的主要作用是为每个任务分配一个线程,当任务完成后,线程会被回收并可供下一个任务使用。
这样,线程的创建和销毁的开销就可以得到控制,避免了频繁创建和销毁线程所带来的性能损失。
二、Java线程池的使用方法1. 创建线程池Java线程池的创建方式非常简单,只需要使用ThreadPoolExecutor类即可。
以下是一个简单的线程池创建代码: ```ExecutorService executor =Executors.newFixedThreadPool(5);```这个代码创建了一个固定大小为5的线程池。
如果需要创建其他类型的线程池,可以使用其他的静态工厂方法,如newCachedThreadPool()、newSingleThreadExecutor()等。
2. 提交任务创建好线程池之后,我们就可以向线程池提交任务了。
以下是一个简单的线程池提交任务代码:```executor.submit(new Runnable() {@Overridepublic void run() {// 执行任务}});```这个代码提交了一个Runnable类型的任务,线程池会自动为其分配一个线程执行。
如果需要提交其他类型的任务,可以使用Callable、Future等接口。
java 线程池参数摘要:1.线程池的概述2.线程池的参数3.线程池参数的使用方法4.线程池参数对性能的影响5.线程池参数的优化建议正文:一、线程池的概述线程池(ThreadPool)是一种用于管理和控制线程数量的机制。
在Java 中,线程池可以通过Executors 类创建,它提供了一系列静态工厂方法来创建不同类型的线程池。
线程池的主要目的是为了提高系统的并发性能和资源利用率,通过合理地配置线程数量,避免因线程创建和销毁带来的性能开销。
二、线程池的参数线程池的参数主要包含以下几个方面:1.线程数量:线程池中同时存在的线程数量。
线程数量的设置要根据任务的类型和系统的负载情况来合理调整,一般而言,线程数量应大于1,但小于等于系统的核数。
2.队列容量:线程池中的任务队列容量。
当线程数量达到最大值且工作队列已满时,新任务将会被拒绝。
因此,队列容量的设置要根据任务的特性和系统的负载情况来合理调整。
3.线程的生命周期:线程的生命周期策略,包括线程的初始化、执行、终止等过程。
线程池提供了三种生命周期策略:固定线程数、单线程、可缓存的线程。
4.拒绝策略:当线程池已满且任务队列已满时,如何处理新任务。
线程池提供了四种拒绝策略:AbortPolicy(默认策略,直接抛出异常)、CallerRunsPolicy(让调用者执行任务)、DiscardPolicy(直接丢弃任务,不抛出异常)、DiscardOldestPolicy(丢弃队列中最旧的任务,然后尝试重新提交新任务)。
5.线程工厂:线程工厂用于创建新的线程。
线程池提供了两种线程工厂:DefaultThreadFactory(默认线程工厂,创建主线程)、ThreadFactory(自定义线程工厂,可以创建具有特定属性的线程)。
三、线程池参数的使用方法要使用线程池的参数,首先需要创建一个线程池实例。
以下是一个创建线程池的示例:```javaimport java.util.concurrent.*;public class ThreadPoolExample {public static void main(String[] args) {int numberOfThreads = 5;int queueCapacity = 10;ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(numberOfThreads, queueCapacity, 0L, LISECONDS, new LinkedBlockingQueue<>(queueCapacity),new ThreadFactory() {private final AtomicInteger threadNumber = new AtomicInteger(1);@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(r, "Thread-" + threadNumber.getAndIncrement());t.setDaemon(false);t.setPriority(Thread.NORM_PRIORITY);return t;}});// 使用线程池执行任务executor.execute(() -> {System.out.println("Hello from thread: " + Thread.currentThread().getName());});// 关闭线程池executor.shutdown();}}```四、线程池参数对性能的影响线程池参数对性能的影响主要体现在以下几个方面:1.线程数量:线程数量的设置要根据任务的类型和系统的负载情况来合理调整。
深入研究线程池一.什么是线程池?线程池就是以一个或多个线程[循环执行]多个应用逻辑的线程集合.注意这里用了线程集合的概念是我生造的,目的是为了区分执行一批应用逻辑的多个线程和线程组的区别.关于线程组的概念请参阅基础部分.一般而言,线程池有以下几个部分:1.完成主要任务的一个或多个线程.2.用于调度管理的管理线程.3.要求执行的任务队列.那么如果一个线程循环执行一段代码是否是线程池?如果极端而言,应该算,但实际上循环代码应该算上一个逻辑单元.我们说最最弱化的线程池应该是循环执行多个逻辑单元.也就是有一批要执行的任务,这些任务被独立为多个不同的执行单元.比如:int x = 0;while(true){x ++;}这就不能说循环中执行多个逻辑单元,因为它只是简单地对循环外部的初始变量执行++操作.而如果已经有一个队列ArrayList al = new ArrayList();for(int i=0;i<10000;i++){al.add(new AClass());}然后在一个线程中执行:while(al.size() != 0){AClass a = (AClass)al.remove(0);a.businessMethod();}我们说这个线程就是循环执行多个逻辑单元.可以说这个线程是弱化的线程池.我们习惯上把这些相对独立的逻辑单元称为任务.二.为什么要创建线程池?线程池属于对象池.所有对象池都具有一个非常重要的共性,就是为了最大程度复用对象.那么线程池的最重要的特征也就是最大程度利用线程.从编程模型模型上说讲,在处理多任务时,每个任务一个线程是非常好的模型.如果确实可以这么做我们将可以使用编程模型更清楚,更优化.但是在实际应用中,每个任务一个线程会使用系统限入"过度切换"和"过度开销"的泥潭.打个比方,如果可能,生活中每个人一辆房车,上面有休息,娱乐,餐饮等生活措施.而且道路交道永远不堵车,那是多么美好的梦中王国啊.可是残酷的现实告诉我们,那是不可能的.不仅每个人一辆车需要无数多的社会资源,而且地球上所能容纳的车辆总数是有限制的.首先,创建线程本身需要额外(相对于执行任务而必须的资源)的开销.作业系统在每创建一个线程时,至少需要创建以下资源:线程内核对象用于对线程上下文的管理.用户模式执行栈.内核模式执行栈.这些资源被线程占有后作业系统和用户都无法使用.相反的过程,销毁线程需要回收资源,也需要一定开销.其次,过多的线程将导致过度的切换.线程切换带来的性能更是不可估量.系统完成线程切换要经过以下过程:从用户模式切换到内核模式.将CPU寄存器的值保存到当前线程的内核对象中.打开一个自旋锁,根据调度策略决定下一个要执行的线程.释放自旋锁,如果要执行的线程不是同一进程中的线程,还需要切换虚拟内存等进程环境.将要执行的线程的内核对象的值写到CPU寄存器中.切换到用户模式执行新线程的执行逻辑.以上开销对于用户要执行的任务而言,都是额外的.更不可容忍的是,如果用户的任务逻辑都是很小的单元,而新分配线程和线程切换的开销与任务逻辑需要的开销的比例可能会10:1,100:1,1000:1.也就是你花了1000$买的衣服只穿了一天!所以线程池的目的就是为了减少创建和切换线程的额外开销,利用已经的线程多次循环执行多个任务从而提高系统的处理能力.也就是在"社会主义初级阶段"一件衣服应该尽量多穿一些天数.[扩展知识]尽管目前绝大多数JVM实现都是一个Java线程对应一个作业系统线程,但事实上(如果是我来实现JVM) 完全可以用一个作业系统线程执行多个Java线程,因为对于作业系统线程来说Java线程就是一个任务. 而且无论是作业系统线程或Java线程中都可以更细地划分为超细线程(纤程),即在线程内部实现对纤程的调度利用纤程来执行任务.三.如何实现线程池?一个线程池至少应该具有以下几个方面的功能:1.提供一个任务接口以便用户加入任务由于Java不支持方法指针,所以操作(方法)只能绑定在对象上,将拥有操作的队象放入队列中,以便工作线程能按一定策略获取对象然后执行其上的方法.这里需要有两个组件,一是规定操作的任务接口:interface ITask{public void task();}一是存放操作的容器.容器可以根据调度策略来选择或自己实现,比如一个最简单的FIFO策略的容器可以用LinkedList来实现.需要注意的是对这个容器的存取需要同步:class TaskList{private LinkedList<ITask> tl = new LinkedList();public synchronized void addTask(ITask task){this.tl.add(task);//notifyAll();}//加上addFistTask和addLastTaskpublic synchronized ITask getTask(){if(this.size() <= 0)wait();return this.tl.poll();}//加上getFistTask和getLastTaskpublic synchronized int getCount(){return this.tl.size();}public synchronized void removeAll(){this.tl.clear();}}加上addFistTask和addLastTask/getFistTask和getLastTask实现就可以实现简单的优先级调度.2.工作线程我们把用来执行用户任务的线程称为工作线程,工作线程就是不断从队列中获取任务对象并执行对象上的业务方法:class WorkThread extends Thread{private TaskList list;//多个工作线程共同从一个任务队列中获取任务,所以要从外面传入一个任务队列.public WorkThread(String name,TaskList list){super(name);this.list = list;}public void run(){while(true){ITask task = null;task = list.getTask();if(task != null) task.task();}}}在基础知识部分已经介绍了对线程状态的标记控制,请参照前面的知识自己加入对线线程状态的判断. 完成了这几个基础部分,就需要有一个对工作线程的调度线程.完成以下几个功能:1.生成需要的工作线程.由于创建线程需要一定的开销,一定要注意所创建的所有线程不能超一个设定的最大值.建议最大值不要超25.2.动态自适应调整集合中线程数.当有太多的线程处于闲置状态时(队列中没有任务),应该按一定比例销毁闲置了一定时的线程.如果队列中任务队列积压太多而工作线程总数没有超最大线程数时应该及时创建工作线程直至达到是大值.3.需要一个专门的后台线程定时扫描队列中任务与正在工作的线程总数,闲置的线程总数.以上功能有不同优化方法实现,可以参考JDK的线程池实现.。
线程池的概念与完整代码示例最近在网上学习了线程池的概念和使用方法,因此想趁着自己空闲的时候,拿出来给大家分享一下。
文章如有不当之处,还望多多指正,个人邮箱:helpylee@Thanks.●线程池引入的必要性:在网络服务器中,包括大量的web服务器,它们都需要在单位时间内必须处理相当数目的接入请求以及数据处理。
通常在传统多线程服务器中是这样实现的:一旦有个请求到达,就创建一个线程,由该线程执行任务,任务执行完毕后,线程就退出。
这也就是通常所说的及时创建,及时销毁策略。
在现代计算机中,尽管创建线程的时间已经大大缩短,但是如果提交给线程的任务是执行时间较短,而且次数非常的频繁,那么服务器就将处于一个不停创建于销毁线程的状态下,这将是一笔不小的开销。
尤其是在线程执行的时间非常短的情况。
线程池就是为了解决上述问题的,它的实现原理是这样的:在应用程序启动之后,就马上创建一定数量的线程,放入空闲的队列中。
这些线程都是处于阻塞状态,这些线程只占一点内存,不占用CPU。
当任务到来后,线程池将选择一个空闲的线程,将任务传入此线程中运行。
当所有的线程都处在处理任务的时候,线程池将自动创建一定的数量的新线程,用于处理更多的任务。
执行任务完成之后线程并不退出,而是继续在线程池中等待下一次任务。
当大部分线程处于阻塞状态时,线程池将自动销毁一部分的线程,回收系统资源。
●线程池概念下面是一个简单线程池的实现,这个线程池的代码是我从网上的一个例子参考到的,程序的整体方案是这样的:程序启动之前,初始化线程池,启动线程池中的线程,由于还没有任务到来,线程池中的所有线程都处在阻塞状态,当一有任务到达就从线程池中取出一个空闲线程处理,如果所有的线程都处于工作状态,就添加到队列,进行排队。
如果队列中的任务个数大于队列的所能容纳的最大数量,那就不能添加任务到队列中,只能等待队列不满才能添加任务到队列中。
本程序由三个文件组成,分别是threadpoll.h,threadpoll.c,main.c,下面的代码已经在64位系统成功运行。
线程池的核心参数和基本原理(二)线程池的核心参数和基本原理什么是线程池线程池是一种多线程处理方式,它包含了一组预先创建的线程,用于执行任务。
线程池通过减少线程的创建和销毁次数,以及对线程的管理和复用,提高了多线程程序的性能和效率。
线程池的核心参数线程池在初始化时通常会提供一些关键参数,以根据实际需求来调整线程池的行为。
以下是线程池的核心参数:1.核心线程数:线程池中最小的线程数。
即使线程池处于空闲状态,核心线程也会一直存在,不会被销毁。
核心线程负责执行任务队列中的任务。
2.最大线程数:线程池中最大的线程数。
当核心线程都在执行任务,并且任务队列已满时,线程池会创建新的线程,直到达到最大线程数。
3.任务队列:用于存储待执行的任务。
线程池会按顺序从任务队列中获取任务,并将其分配给核心线程执行。
4.空闲线程存活时间:当线程池处于空闲状态,并且当前线程数大于核心线程数时,空闲线程的存活时间。
超过该时间后,空闲线程会被销毁。
5.拒绝策略:当任务队列已满且线程达到最大线程数时,新的任务无法被执行时所采取的策略。
常见的拒绝策略有直接抛出异常、丢弃任务、丢弃任务队列中最旧的任务和由调用线程执行任务。
线程池的基本原理线程池的基本原理可以分为以下几个步骤:1.初始化线程池,创建一组核心线程,线程数与核心线程数相等。
2.当有新的任务提交给线程池时,线程池会将任务添加到任务队列中。
3.核心线程会从任务队列中不断地获取任务进行执行。
4.当任务队列已满且当前线程数小于最大线程数时,线程池会创建新的线程来执行任务。
5.如果当前线程数已经达到最大线程数,并且任务队列已满,则根据设定的拒绝策略来处理新的任务。
6.线程在执行完任务后,会根据设定的空闲线程存活时间来决定是否销毁自身。
通过以上步骤,线程池能够高效地利用线程资源来处理大量的任务,并且还能控制线程的数量,避免线程过多导致系统资源耗尽。
总结线程池是一种管理多线程的机制,通过设置核心参数来控制线程的行为。
Java线程池使用与配置指南1. 引言在Java编程中,线程池是一个非常重要的概念。
它可以帮助我们更好地管理和控制线程的创建和执行,提高程序的性能和效率。
本文将介绍Java线程池的使用和配置指南,帮助读者更好地理解和应用线程池。
2. 线程池的概念和作用线程池是一种用于管理和复用线程的机制。
它可以在程序启动时创建一定数量的线程,这些线程可以被重复使用来执行任务,而不需要每次都创建新的线程。
线程池可以有效地减少线程的创建和销毁的开销,提高程序的性能和效率。
线程池的主要作用有:- 控制线程的数量:线程池可以限制同时执行的线程数量,避免线程过多导致系统资源的浪费和竞争。
- 提高线程的复用性:线程池可以复用已经创建的线程,避免频繁地创建和销毁线程,提高程序的效率。
- 提供任务队列:线程池可以提供一个任务队列,用于存储等待执行的任务。
当线程池中的线程空闲时,可以从任务队列中取出任务进行执行。
3. Java线程池的使用在Java中,线程池的使用非常简单。
我们可以通过java.util.concurrent包中的ThreadPoolExecutor类来创建和管理线程池。
首先,我们需要创建一个ThreadPoolExecutor对象,可以通过以下方式来创建:```javaThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit, BlockingQueue);```其中,corePoolSize表示核心线程数,即线程池中能够同时执行的线程数量;maximumPoolSize表示线程池中最大的线程数量;keepAliveTime表示线程的存活时间;TimeUnit表示存活时间的单位;BlockingQueue表示任务队列。
然后,我们可以通过executor的execute方法来提交任务:```javaexecutor.execute(new Runnable() {@Overridepublic void run() {// 任务的具体逻辑}});```这样,线程池会自动从任务队列中取出任务,并将其分配给空闲的线程进行执行。
线程池使用方式线程池是多线程编程中很重要的一个概念,它可以有效地管理和复用线程,从而提高程序的性能和效率。
在实际的软件开发中,线程池被广泛应用于服务器端程序、Web应用、桌面应用等各种领域。
本文将介绍线程池的使用方式,包括线程池的基本原理、创建线程池的方法、线程池的配置参数以及线程池的最佳实践。
一、线程池的基本原理线程池是一种管理线程的机制,它在程序启动时创建一定数量的线程放入线程池中,然后根据需要动态地调整线程的数量,从而满足任务的执行需求。
线程池可以有效地避免频繁地创建和销毁线程,减少了线程创建和销毁的开销,提高了程序的性能。
在线程池中,有一个任务队列用于存放需要执行的任务。
当有新的任务到来时,线程池会从任务队列中获取一个空闲的线程来执行任务,如果队列中没有空闲线程,则根据配置的参数来创建新的线程。
当任务执行完毕后,线程将会返回到线程池中,等待下一个任务的到来。
二、创建线程池的方法在Java中,线程池是通过`java.util.concurrent`包提供的`Executor`框架来实现的。
`Executor`框架定义了`ExecutorService`接口,通过该接口可以创建并管理线程池。
下面是一种常见的创建线程池的方式:```javaExecutorService executor = Executors.newFixedThreadPool(10);```上面的代码创建了一个固定大小为10的线程池。
`Executor`框架还提供了其他类型的线程池,例如`CachedThreadPool`、`SingleThreadExecutor`和`ScheduledThreadPool`等,开发者可以根据具体的应用场景来选择合适的线程池类型。
除了通过`Executor`框架提供的工厂方法来创建线程池之外,也可以通过`ThreadPoolExecutor`类来手动创建线程池,并且对线程池的各种参数进行详细的配置。
线程池的返回值一、线程池的概念和作用线程池是一种多线程处理方式,它可以在系统启动时创建一定数量的线程放入池中,当有任务需要处理时,从池中取出一个空闲的线程进行处理。
其作用主要有以下三个方面:1. 提高系统性能:使用线程池可以减少线程创建和销毁的开销,避免因频繁创建和销毁大量线程而导致系统性能下降。
2. 提高任务处理效率:使用线程池可以使多个任务并发执行,提高任务处理效率。
3. 控制并发数:使用线程池可以限制同时执行任务的数量,防止因过度并发而导致系统资源耗尽。
二、线程池的返回值1. submit方法返回Future对象在Java中,提交任务到线程池时常用的方法是submit()方法。
该方法会返回一个Future对象,表示异步计算的结果。
通过该对象可以获取异步计算结果或者取消异步计算。
2. execute方法没有返回值与submit()方法不同,execute()方法没有返回值。
它只是将任务提交给线程池执行,并且不会等待任务执行完成。
3. 实现Callable接口并返回结果除了使用submit()方法外,还可以通过实现Callable接口来提交任务到线程池,并且返回计算结果。
Callable接口类似于Runnable接口,但是它可以返回计算结果,并且可以抛出异常。
在提交任务时,需要使用submit()方法,并将Callable对象作为参数传入。
4. 实现Runnable接口并在外部保存结果除了使用Callable接口外,还可以通过实现Runnable接口来提交任务到线程池。
但是由于Runnable接口没有返回值,因此需要在外部保存计算结果。
一种常见的做法是使用一个共享变量来保存结果,在任务执行完成后将结果存储到该变量中。
三、Future对象的使用1. 获取异步计算结果Future对象表示异步计算的结果,它提供了一系列方法来获取计算结果。
其中最常用的方法是get()方法,该方法会阻塞当前线程直到异步计算完成,并返回计算结果或者抛出异常。
ios线程池实现原理iOS线程池是iOS开发中常用的一种多线程管理方式。
它可以用来管理和调度多个线程,以提高应用程序的性能和响应速度。
本文将介绍iOS线程池的实现原理和使用方法。
一、什么是线程池线程池是一种用来管理和复用线程的技术。
在应用程序中,创建和销毁线程是一项开销较大的操作,过多的线程创建和销毁会耗费大量的系统资源。
而线程池可以在应用程序启动时创建一定数量的线程,并将其保存在一个线程队列中。
当需要执行任务时,线程池会从队列中取出一个空闲线程来执行任务,并在任务完成后将线程返回给线程池,以便复用。
二、iOS线程池的实现原理iOS线程池的实现主要依靠三个核心组件:任务队列、线程管理器和线程池。
1. 任务队列:用于存储待执行的任务。
当一个任务到达时,会被添加到任务队列中等待执行。
2. 线程管理器:负责管理线程的创建、销毁和回收。
线程管理器会根据需要动态地创建新线程,并在线程完成任务后将其回收。
3. 线程池:线程池是整个iOS线程池系统的核心。
它通过与任务队列和线程管理器的协作,实现线程的复用和任务的调度。
线程池会根据任务队列中的任务数和线程池中的线程数动态调整线程的数量,以保持系统的高效运行。
三、iOS线程池的使用方法在iOS开发中,使用线程池可以很方便地实现多线程操作。
以下是使用iOS线程池的基本步骤:1. 创建线程池:使用线程池的第一步是创建一个线程池对象。
可以通过调用相关API来创建线程池,如`NSOperationQueue`。
2. 创建任务:在使用线程池之前,需要先创建一些任务。
任务可以是一个方法、一个函数或一个代码块。
任务的实现应该尽量简洁并具有独立性,以便能够被线程池并发执行。
3. 将任务添加到线程池:创建任务后,可以通过调用线程池的相关方法将任务添加到线程池中。
线程池会根据任务的优先级和当前线程池的状态来决定任务的执行顺序。
4. 线程池的状态管理:线程池通常有三种状态:运行、暂停和停止。
Linux下设计一个简单的线程池定义什么是线程池?简单点说,线程池就是有一堆已经创建好了的线程,初始它们都处于空闲等待状态,当有新的任务需要处理的时候,就从这个池子里面取一个空闲等待的线程来处理该任务,当处理完成了就再次把该线程放回池中,以供后面的任务使用。
当池子里的线程全都处理忙碌状态时,线程池中没有可用的空闲等待线程,此时,根据需要选择创建一个新的线程并置入池中,或者通知任务线程池忙,稍后再试。
为什么要用线程池?我们说,线程的创建和销毁比之进程的创建和销毁是轻量级的,但是当我们的任务需要大量进行大量线程的创建和销毁操作时,这个消耗就会变成的相当大。
比如,当你设计一个压力性能测试框架的时候,需要连续产生大量的并发操作,这个是时候,线程池就可以很好的帮上你的忙。
线程池的好处就在于线程复用,一个任务处理完成后,当前线程可以直接处理下一个任务,而不是销毁后再创建,非常适用于连续产生大量并发任务的场合。
线程池工作原理线程池中每一个线程的工作过程如下:图1:线程的工作流程线程池的任务就在于负责这些线程的创建,销毁和任务处理参数传递、唤醒和等待。
1. 创建若干线程,置入线程池2. 任务达到时,从线程池取空闲线程3. 取得了空闲线程,立即进行任务处理4. 否则新建一个线程,并置入线程池,执行35. 如果创建失败或者线程池已满,根据设计策略选择返回错误或将任务置入处理队列,等待处理6. 销毁线程池图2:线程池的工作原理线程池设计数据结构设计任务设计view plaincopy to clipboard1typedef struct tp_work_desc_s TpWorkDesc;2typedef void (*process_job)(TpWorkDesc*job);3struct tp_work_desc_s {4void *ret; //call in, that is arguments5void *arg; //call out, that is return value6};其中,TpWorkDesc是任务参数描述,arg是传递给任务的参数,ret则是任务处理完成后的返回值;process_job函数是任务处理函数原型,每个任务处理函数都应该这样定义,然后将它作为参数传给线程池处理,线程池将会选择一个空闲线程通过调用该函数来进行任务处理;线程设计view plaincopy to clipboard7typedef struct tp_thread_info_s TpThreadInfo;8struct tp_thread_info_s {9 pthread_t thread_id; //thread id num10 TPBOOL is_busy; //thread status:true-busy;flase-idle11 pthread_cond_t thread_cond;12 pthread_mutex_t thread_lock;13 process_job proc_fun;14 TpWorkDesc* th_job;15 TpThreadPool* tp_pool;16};TpThreadInfo是对一个线程的描述。
线程池的通俗理解
线程池可以看做容纳线程的容器
1.为什么要使用线程池
在java中,如果每个请求到达就创建一个新线程,开销是相当大的。
在实际使用中,
创建和销毁线程花费的时间和消耗的系统资源都相当大,甚至可能要比在处理实际的用户
请求的时间和资源要多的多。
除了创建和销毁线程的开销之外,活动的线程也需要消耗系
统资源。
如果在一个jvm里创建太多的线程,可能会使系统由于过度消耗内存或“切换过度”而导致系统资源不足。
为了防止资源不足,需要采取一些办法来限制任何给定时刻处
理的请求数目,尽可能减少创建和销毁线程的次数,特别是一些资源耗费比较大的线程的
创建和销毁,尽量利用已有对象来进行服务。
线程池主要用来解决线程生命周期开销问题和资源不足问题。
通过对多个任务重复使用线程,线程创建的开销就被分摊到了多个任务上了,而且由于在请求到达时线程已经存在,所以消除了线程创建所带来的延迟。
这样,就可以立即为请求服务,使用应用程序响应更快。
另外,通过适当的调整线程中的线程数目可以防止出现资源不足的情况。
2.线程池的组成部分
一个比较简单的线程池至少应包含线程池管理器、工作线程、任务列队、任务接口等部分。
其中线程池管理器的作用是创建、销毁并管理线程池,将工作线程放入线程池中;工
作线程是一个可以循环执行任务的线程,在没有任务是进行等待;任务列队的作用是提供
一种缓冲机制,将没有处理的任务放在任务列队中;任务接口是每个任务必须实现的接口,主要用来规定任务的入口、任务执行完后的收尾工作、任务的执行状态等,工作线程通过
该接口调度任务的执行。
线程池管理器至少有下列功能:创建线程池,销毁线程池,添加新任务。
工作线程是一个可以循环执行任务的线程,在没有任务时将等待。
任务接口是为所有任务提供统一的接口,以便工作线程处理。
任务接口主要规定了任
务的入口,任务执行完后的收尾工作,任务的执行状态等。
下面举个例子来详细说说
现在我们想线程池中添加100个任务,看线程池中线程数量是如何变化的,加深我们的理解。
默认线程池中线程下限是5,上限25.
总结:线程池是为突然大量爆发的线程设计的,通过有限的几个固定线程为大量的操作服务,减少了创建和销毁线程所需的时间,从而提高效率。
线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。
线程池线程都是后台线程.每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中.
本文出自黑马程序员,黑马论坛。