`
huangyongxing310
  • 浏览: 496031 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

Java 线程池工作原理

阅读更多
Java 线程池工作原理


背景和目的:
1.假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。
如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能。
2.如果每个任务到来都进行线程的创建,运行完成后再消毁线程,当任务请求非常多时,应用就有非常多的线程同时创建,
运行时就有非常多的线程进行切换,这种对系统资源的开销是非常大的。
3.除了创建和销毁线程的开销之外,活动的线程也消耗系统资源。在一个JVM 里创建太多的线程可能会导致系统由于过度
消耗内存而用完内存或“切换过度”。
4.线程池就是为了解决上述问题提出的解决方案。
5.Java中的ThreadPoolExecutor类是实现线程池的一个类。


线程池四个基本组成部分:
1、线程池管理器(ThreadPool):用于创建并管理线程池,包括创建线程池,销毁线程池,添加新任务;
2、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务,工作线程是线程池进行创建和销毁的(无需人为创建);
3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
4、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。(任务就是自己按业务需求进行编写的(实现implements Runnable接口run)实例对象)


线程池工作原理:
1.应用启动时就进行若干个工作线程的初始化,并存入线程池中。这样工作线程(ThreadPoolExecutor中Worker)就创建了。
2.任务到达时,将任放到任务队列(ThreadPoolExecutor中workQueue)中。(如:threadPoolExecutor.execute(myTask);)
3.工作线程从任务队列中取出任务并运行任务接口进行任务的处理。
4.当任务队列中的任务非常多时,线程池管理器就会创建新的工作线程(ThreadPoolExecutor中Worker)放入线程池中,新的工作线程也进行任务的处理。
5.这样做就减少了应用中线程的个数,运行任务时没有进行线程的创建;线程个数减少,线程切换的系统开销也就减少了。
6.就是将任务就成一个实例(实现implements Runnable接口run),并创建指定个线程(ThreadPoolExecutor中Worker)不断地从任务队列(ThreadPoolExecutor中workQueue)
中取出任务实例,并运行实例中的run方法。



Java中的ThreadPoolExecutor类
public class ThreadPoolExecutor extends AbstractExecutorService {
    .....
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue);

    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory);

    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler);

    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
        BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);
    ...
}


1.corePoolSize:核心池的大小,(主工作线程的个数)
2.maximumPoolSize:线程池最大线程数(比corePoolSize大的都是临时的,需要的时候才创建放到线程池中)
3.keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。
4.unit:参数keepAliveTime的时间单位,
TimeUnit.DAYS;               //天
TimeUnit.HOURS;             //小时
TimeUnit.MINUTES;           //分钟
TimeUnit.SECONDS;           //秒
TimeUnit.MILLISECONDS;      //毫秒
TimeUnit.MICROSECONDS;      //微妙
TimeUnit.NANOSECONDS;       //纳秒

5.workQueue:一个阻塞队列,用来存储等待执行的任务,
6.threadFactory:线程工厂,主要用来创建线程;
7.handler:表示当拒绝处理任务时的策略,有以下四种取值:
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务




ThreadPoolExecutor类中其他的一些比较重要成员变量
private final BlockingQueue<Runnable> workQueue;              //任务缓存队列,用来存放等待执行的任务
private final ReentrantLock mainLock = new ReentrantLock();   //线程池的主要状态锁,对线程池状态(比如线程池大小
                                                              //、runState等)的改变都要使用这个锁
private final HashSet<Worker> workers = new HashSet<Worker>();  //用来存放工作集

private volatile long  keepAliveTime;    //线程存货时间
private volatile boolean allowCoreThreadTimeOut;   //是否允许为核心线程设置存活时间
private volatile int   corePoolSize;     //核心池的大小(即线程池中的线程数目大于这个参数时,提交的任务会被放进任务缓存队列)
private volatile int   maximumPoolSize;   //线程池最大能容忍的线程数

private volatile int   poolSize;       //线程池中当前的线程数

private volatile RejectedExecutionHandler handler; //任务拒绝策略

private volatile ThreadFactory threadFactory;   //线程工厂,用来创建线程

private int largestPoolSize;   //用来记录线程池中曾经出现过的最大线程数

private long completedTaskCount;   //用来记录已经执行完毕的任务个数




任务的提交
execute()	//这个方法可以向线程池提交一个任务,交由线程池去执行。
submit()	//这个方法也是用来向线程池提交任务的,但是它和execute()方法不同,它能够返回任务执行的结果
shutdown()	//线程池处于SHUTDOWN状态,此时线程池不能够接受新的任务,它会等待所有任务执行完毕
shutdownNow()	//线程池处于STOP状态,此时线程池不能接受新的任务,并且会去尝试终止正在执行的任务



例子:
package ThreadPool;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPool {
	public static void main(String[] args) {
		ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10, 200, TimeUnit.MILLISECONDS,
				new LinkedBlockingQueue(100));

		for (int j = 0; j < 16; j++) {
			for (int i = 0; i < 16; i++) {
				MyTask myTask = new MyTask(j*100+i);
				threadPoolExecutor.execute(myTask);
				System.out.println("线程池中线程数目:" + threadPoolExecutor.getPoolSize() + ",队列中等待执行的任务数目:" + threadPoolExecutor.getQueue().size()
						+ ",已执行完的任务数目:" + threadPoolExecutor.getCompletedTaskCount());
			}
		}
		threadPoolExecutor.shutdown();
	}
}


package ThreadPool;

class MyTask implements Runnable { //实现接口Runnable接口run,
	private int taskNum;

	public MyTask(int num) {
		this.taskNum = num;
	}

	public void run() {//接口run,你的任务逻辑在这里实现
		System.out.println("正在执行task " + this.taskNum);
		System.out.println("task " + taskNum + "执行完毕");
	}
}



spring线程池(TaskExecutor)
参考原文:http://lishaorui.iteye.com/blog/1051823


参考原文:http://www.cnblogs.com/dolphin0520/p/3932921.html
参考原文:http://www.blogjava.net/stevenjohn/archive/2011/12/12/366161.html
参考原文:http://wenku.baidu.com/link?url=GoqD2-ouxAVhPVfs20rqelSjDPs8IPHq6dQanWuJpca8Em9yxiGMLoHS2-1Pyq8tec9Z25z8FiqDJBhWhKUSAd82YEW4Bu7wio7JTHUp3YG


https://www.cnblogs.com/zhaoyan001/p/7049627.html
分享到:
评论

相关推荐

    Java 线程池的原理与实现

    理解Java线程池的原理和实现,可以帮助我们更有效地管理并发任务,提升系统性能,同时避免资源浪费和线程安全问题。在实际开发中,合理配置线程池参数,结合业务场景选择合适的线程池类型,是优化系统性能的关键步骤...

    JAVA线程池的原理与实现.pdf

    Java线程池是一种高效利用系统资源、管理并发执行任务的机制。...总的来说,理解Java线程池的工作原理和实现对于优化并发应用程序至关重要,它可以帮助我们更好地控制系统的并发度,提高系统的响应速度和资源利用率。

    深入探索:Java线程池的工作原理与实践

    本文将深入探讨Java线程池的工作原理,并通过实际代码示例,展示如何高效地使用线程池。 Java线程池是并发编程中的一个重要工具,它通过减少线程创建和销毁的开销,提高了程序的性能和资源利用率。理解线程池的...

    java线程池封装j

    本文将深入探讨Java线程池的原理、封装以及相关知识点。 ### 1. Java线程池概念 Java线程池由`java.util.concurrent`包中的`ExecutorService`接口和其子类实现。其中,最常用的是`ThreadPoolExecutor`类,它提供了...

    Java concurrency线程池之线程池原理(一)_动力节点Java学院整理

    Java concurrency线程池之线程池原理(一)_动力节点Java学院整理,动力节点口口相传的Java黄埔军校

    资料:Java线程池实现原理及其在美团业务中的实践

    资料:Java线程池实现原理及其在美团业务中的实践

    Java线程池的原理及几类线程池的介绍.docx

    ### Java线程池的原理及几类线程池的介绍 #### 一、线程池的概念与作用 在计算机编程中,线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。Java语言支持多线程编程,使得...

    JAVA线程池原理以及几种线程池类型介绍

    ### JAVA线程池原理及几种线程池类型的详细介绍 #### 一、线程池的引入背景及重要性 在现代软件开发中,特别是在基于Java的应用程序设计中,线程池技术已经成为提高系统性能和资源利用率的关键手段之一。线程池...

    深入理解Java线程池(PPT:原理+代码)

    通过剖析Java中线程池的原理,解读Java线程池源码,并给出线程池调用的示例,帮助理解线程池的基本原理。

    自定义实现Java线程池

    ### 自定义实现Java线程池 #### 一、概述 在深入探讨自定义Java线程池之前,我们先简要回顾一下线程池的基本概念及其重要性。线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动...

    JAVA线程池原理以及几种线程池类型介绍.doc

    Java线程池是一种高效管理线程的工具,它允许开发者预先创建一组线程,并复用它们来处理任务,从而降低了创建和销毁线程的开销。线程池的使用尤其适用于处理大量短小任务的场景,例如Web服务器、数据库服务器等。在...

    Java线程池文档

    Java线程池是一种高效管理线程的机制,它允许开发者预先设定线程的数量,并通过池化的方式重用已创建的线程,以提高系统性能,减少线程的创建和销毁开销。线程池在Java中是通过`java.util.concurrent`包下的`...

    java线程池实例

    Java线程池是一种高效管理线程资源的工具,它通过维护一组可重用的线程来减少创建和销毁线程的开销。在Java中,`java.util.concurrent`包提供了`ExecutorService`接口和它的实现类,如`ThreadPoolExecutor`,来支持...

    java 线程池实现多并发队列后进先出

    Java线程池是一种高效管理并发任务的机制,它允许开发者预先配置一定数量的线程,以便在处理多个并发任务时能有效地复用这些线程,从而避免了频繁创建和销毁线程带来的开销。在Java中,`java.util.concurrent`包下的...

    JAVA线程池例子

    Java线程池是一种高效管理线程资源的技术,它允许开发者创建一组可重用的工作线程,从而避免频繁地创建和销毁线程带来的性能开销。线程池在Java中主要通过`java.util.concurrent`包中的`ExecutorService`接口及其...

    Java线程池及观察者模式解决多线程意外死亡重启问题

    线程池的工作原理是通过维护一个工作线程集合,当提交任务时,线程池会从队列中选择一个空闲线程来执行任务,而不是每次都创建新的线程。这样可以避免频繁的线程创建和销毁带来的开销。线程池可以通过设置核心线程数...

    Java线程池.pdf

    ### Java线程池详解 #### 引言 在现代计算机科学中,线程作为轻量级的进程,已经成为操作系统和应用程序提高并发性、优化资源...理解和掌握Java线程池的原理和使用方法,对于开发高性能、高可靠的Java应用至关重要。

    基于Java线程池技术的数据爬虫设计与实现.pdf

    本文所提及的基于Java线程池技术的数据爬虫设计与实现,不仅涉及到了数据爬虫的原理和架构,还包括了多线程编程的知识点,以及线程池技术在数据爬虫中的具体应用。 首先,数据爬虫的基本原理是模拟用户的点击行为,...

    了解Java线程池执行原理

    Java线程池执行原理 Java线程池执行原理是Java中的一种机制,使得线程可以复用,即执行完一个任务后,不被销毁,而是可以继续执行其他的任务。这种机制是通过线程池来实现的,在Java中,线程池是由...

Global site tag (gtag.js) - Google Analytics