`
wdt1988520
  • 浏览: 15513 次
社区版块
存档分类
最新评论

线程池

 
阅读更多

线程池在java中非常重要,在java se1.4以前的版本线程池非常简单,但在1.5以后新增了java.util.concurrent多线包,使线程池变的非常强大!再和java se1.4新增的NIO可以实现非常高性能的功能。

 

为什么使用线程池:

  1、减少线程的创建销毁所到来的资源消耗,线程池可以使线程得到复用,并且易于维护管理。

  2、可更具系统资源消耗(如、cpu、rom、IO)动态配置线程的使用,防止系统消耗过大导致系统奔溃。

 

线程池的分类:

   一、同步线程池

              工作队列选用的SynchronousQueue,SynchronousQueue(一进一出)它将任务交给它的线程并不保                 存任务,如果有新的任务加入线程池就会创建新的线程并立即执行。

              Executors.newCachedThreadPool() 的实现就是SynchronousQueue完成的。

   二、无界线程池

             工作队列选用的LinkedBlockingQueue.

                   1、当线程池的线程数未达到corePoolSize时则创建新的线程执行任务,直到到达饱和线程值                                corePoolSize

                   2、当达到corePoolSize时,新来的任务请求直接加入到无界队列中,如果有无限的任务,直到                           系统被撑爆才停止。

                   3、由于要队列中不能添加新任务,线程池才会新建线程直到达到最大线程值maximumPoolSize                       ,由于这里是无界队列,所以这个最大线程值maximumPoolSize永远达不到!

                       Executors.newFixedThreadPool(10);Executors.newSingleThreadExecutor();就采用的这种实                        现方式.

   三、有界线程池

             工作队列选用的ArrayBlockingQueue.

                线程池的饱和值在maximumPoolSize运行,在最大线程值运行时,新加入的任务采用4种策略模式                               处理。

                有界队列要依靠系统的配置参数作为依据设置有界队列的大小。

               1、 当队列太小,池线程数太大,这样会增加CPU资源的开销,这样线程调度的开销(上下文切                                  换)也会增加,从而降低吞吐量。

               2、 当队列太大,池线程数太小,这样虽可以减小CPU资源的消耗和线程上下文(系统到用户空                                 间)切换带来的开销,但吞吐量也不会高。

              

             有界队列线程池java se中没有实现,我们可以自己更具系统资源来实现自己的线程池。

        

 

执行器的五种状态:

1、RUNNING 在ThreadPoolExecutor被实例化时就是这个状态

2、SHUTDOWN 这一方法是不在接受新的任务,等待池中和队列中的任务完成后关闭,

    ThreadPoolExecutor的awaitTermination()阻塞等待shutdown请求后所有线程终止,会有时间参数,超时和中断也会令方法调用结束。

3、STOP状态执行的是ShutDownNow方法,不在执行池中和队列中的任务,并试图终止正在执行的任务

4、TIDYING线程池为空,就会处于这个状态,执行terminated方法

5、TERMINATED terminated()执行完毕,就会到这个状态,此时ThreadPoolExecutor终结

 

 

例:有界队列的四种策略方式

 

package threadpool;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 *create by datao.wang 2014-2-12-下午3:08:47	
 *有界队列线程池
 *ThreadPoolExecutor 是ExecutorService线程接口的实现
 *ThreadPoolExecutor poolExecutor=new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory , rejectedExecutionHandler);
 *	corePoolSize 是线程池的核心线程数,通常线程池会维持这个线程数
 *	maximumPoolSize 是线程池所能维持的最大线程数
 *	keepAliveTime 和 unit 则分别是超额线程的空闲存活时间数和时间单位
 *	workQueue 是提交任务到线程池的入队列
 *	threadFactory 是线程池创建新线程的线程构造器
 *	rejectedExecutionHandler 是当线程池不能接受提交任务的时候的处理策略
 *
 */
public class ArrayBlockingThreadPoolExecutor {
	//有界队列 队列大小为10
	ArrayBlockingQueue<Runnable> jobs = new ArrayBlockingQueue<Runnable>(10);
	/**
	 * create by datao.wang  2014-2-12
	 * 这是ThreadPoolExecutor默认的一个策略
	 * 作用:当线程池到达最高线程数6,并且有界队列已满,线程池抛出rejectedExecutorException异常
	 */
	public void policy_Abort(){
		RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy();
		ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(2, 6, 30, TimeUnit.SECONDS,jobs,rejectedExecutionHandler );
		runWorker(poolExecutor);
	}
	
	/**
	 * create by datao.wang  2014-2-12
	 * 丢弃策略
	 * 当线程池到达最高线程数6,并且有界队列已满,新加入任务将被丢弃
	 */
	public void policy_Discard(){
		RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.DiscardPolicy();
		ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(2, 6, 30, TimeUnit.SECONDS,jobs,rejectedExecutionHandler );
		runWorker(poolExecutor);
	}

	/**
	 * create by datao.wang  2014-2-12
	 * 丢弃最旧的任务策略
	 * 当线程池到达最高线程数6,并且有界队列已满,新来的任务将队列最前端的任务踢掉。
	 */
	public void policy_DiscardOldest(){
		RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.DiscardOldestPolicy();
		ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(2, 6, 30, TimeUnit.SECONDS,jobs,rejectedExecutionHandler );
		runWorker(poolExecutor);
	}
	
	/**
	 * create by datao.wang  2014-2-12
	 * Caller线程运行策略,任务发起者现在来执行任务策略
	 * 当线程池到达最高线程数6,并且有界队列已满,此时将由任务发起者来执行新来的任务
	 */
	public void policy_CallerRuns(){
		RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.CallerRunsPolicy();
		ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(2, 6, 30, TimeUnit.SECONDS,jobs,rejectedExecutionHandler );
		runWorker(poolExecutor);
	}
	
	public void runWorker(ThreadPoolExecutor poolExecutor){
		int numJobs = 20;
		System.out.println("Starting application to add "+ numJobs + " jobs");
		for (int i=1; i<= numJobs; i++){
			try {
				WorkerThread job=new WorkerThread(i);
				poolExecutor.submit(job);
			//	 System.out.println("Added job #" + (i));
			}catch (RejectedExecutionException e) {
//				e.printStackTrace();
		      System.err.println("RejectedExecutionException job #" + (i));
		    }
		}
	}
	
	public static void main(String[] args) {
		ArrayBlockingThreadPoolExecutor executor=new ArrayBlockingThreadPoolExecutor();
//		executor.policy_Abort();//运行结果当运行到6个任务时将抛出RejectExecutorException异常,后面的任务将继续执行,导致结构有一部分任务未被执行。
//		executor.policy_Discard();//运行结果当运行到6个任务时将放弃后面的几个任务,然后后面的任务将继续执行。
//		executor.policy_DiscardOldest();//运行结果当运行到6个任务是放弃队列最前端的任务,然后后面任务继续执行。
		executor.policy_CallerRuns();//运行结果当运行到6个任务时队列已满,后面新加的任务将由任务提交者线程来执行,这样将减缓任务的提交,结果所以线程都得到执行。
	}
}


/***
 * 工作线程
 * @author wdt
 *
 */
class WorkerThread implements Runnable {
	int jobid;
	
	public WorkerThread (int jobid){
		this.jobid = jobid;
	}
	
	public void run (){
		try{
			System.out.println("exec job" + (jobid)+"---"+(jobid*500+1000));
			//线程睡眠时间
			Thread.sleep(jobid*500 + 1000);
		}catch (Exception excep){
			
		}
	}
}

 

 

 

例:无界队列

package threadpool;

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

/**
 *create by datao.wang 2014-2-13-上午12:02:17	
 *无界队列线程池
 *ThreadPoolExecutor 是ExecutorService线程接口的实现
 *ThreadPoolExecutor poolExecutor=new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory , rejectedExecutionHandler);
 *无界队列的特点:
 * 1、当线程池的线程数未达到corePoolSize时则创建新的线程执行任务,直到到达饱和线程值corePoolSize
 * 2、当达到corePoolSize时,新来的任务请求直接加入到无界队列中,如果有无限的任务,直到系统被撑爆才停止。
 * 3、由于要队列中不能添加新任务,线程池才会新建线程直到达到最大线程值maximumPoolSize,由于这里是无界队列,所以这个最大线程值maximumPoolSize永远达不到!
 */
public class LinkedBlockingThreadPoolExecutor {

	public static void main(String[] args) {
		LinkedBlockingQueue<Runnable> jobs = new LinkedBlockingQueue<Runnable>();
		ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(2, 6, 30, TimeUnit.SECONDS,jobs);
	}
}

 

例:同步队列

package threadpool;

import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 *create by datao.wang 2014-2-13-上午12:21:49	
 *同步队列线程池  (一进一出)
 *同步队列自身的特性:
 *  1、size永远为0
 *  2、当向队列中放入元素(执行put方法)时,队列就发生阻塞,直到有线程调用take方法取走元素。
 *  
 */
public class SynchronousQueueThreadPoolExecutor {
	
	public static void main(String[] args) {
		SynchronousQueue<Runnable> jobs = new SynchronousQueue<Runnable>();
		//同步队列也执行策略模式
		RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.CallerRunsPolicy();
		ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(2, 6, 30, TimeUnit.SECONDS,jobs,rejectedExecutionHandler );
	}
}

 

 例:java se中已实现线程池。

  

package threadpool;

import java.util.concurrent.Executors;

/**
 *create by datao.wang 2014-2-13-上午11:36:48	
 */
public class ExecutorTool {
	
   public static void main(String[] args) {
	   /**
	    * 无限大小的线程池(受限jvm内存),当线程执行完任务会自动重用
	    * 空闲线程也会被回收(默认60秒)
	    * 实现队列为:SynchronousQueue
	    */
	   Executors.newCachedThreadPool(); 
	   /**
	    * 固定线程数的线程池
	    * 实现队列为:LinkedBlockingQueue
	    */
	   Executors.newFixedThreadPool(10);
	   /**
	    * 单线程执行器,线程池只有一个线程,所以线程按顺序执行,当一个线程异常结束时
	    * 会创建新的线程替代。     
	    * 实现队列为:LinkedBlockingQueue
	    */
	   Executors.newSingleThreadExecutor(); 
	   /**
	    * 创建一个无限大小的线程池,周期执行任务
	    * 实现队列为:DelayedWorkQueue
	    */
	   Executors.newScheduledThreadPool(10);//创建核心线程数10的时间相关线程池
	   
	   /***********************************************************************/
	   //以上线程池的创建都是通过ThreadPoolExecutor的构造方法创建的。
   }
}

 

 

分享到:
评论

相关推荐

    线程池  

    线程池是一种多线程处理形式,通过预先创建一定数量的线程并管理它们,以提高系统的效率和响应性。在计算机科学中,特别是在软件开发领域,线程池是操作系统或者编程语言中的一种资源管理技术。它允许程序预先启动一...

    java线程池概念.txt

    corePoolSize:核心池的大小,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中; ...

    阻塞线程池 阻塞线程池 阻塞线程池

    阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池...

    C++实现线程池详解(基于boost源码以及封装等线程池)

    一、要实现高效的线程池,可以考虑以下几点 二、实现线程池可以按照以下步骤进行 三、简单的C++线程池代码示例 四、 基于boost编写的源码库 - 线程池 4.1 基于boost编写的源码库地址 4.2 boost线程池的先进先出、...

    线程池原理及创建(C++实现)

    ### 线程池原理及创建(C++实现) #### 一、线程池的重要性 在现代计算环境中,网络服务器面临着处理大量并发请求的挑战,其中包括但不限于Web服务器、电子邮件服务器和数据库服务器。这类服务器通常需要在短时间...

    java线程池使用后到底要关闭吗

    java线程池使用后到底要关闭吗 java线程池是一种高效的并发编程技术,可以帮助开发者更好地管理线程资源,提高系统的性能和可靠性。然而,在使用java线程池时,一个常见的问题是:使用完线程池后到底要不要关闭?...

    Django异步任务线程池实现原理

    文章通过实例展示了如何创建一个全局线程池类,该类中封装了线程池对象,并提供了向线程池提交任务、检查任务是否在运行等方法。全局线程池的生命周期与Django主线程的生命周期一致,确保了线程资源的合理释放。 5....

    windows线程池,使用Windows自带的线程池api功能,比你写的线程池性能好得多

    线程池是多线程编程中的一个重要概念,它是一种线程使用模式,通过预先创建一组线程并维护一个线程集合来处理并发任务。在Windows操作系统中,内建的线程池API(Thread Pool API)提供了高效且灵活的线程管理机制,...

    一个简单线程池的实现

    线程池是一种在多线程编程中非常重要的概念,它能有效地管理和调度系统中的线程资源,从而提高系统的效率和响应速度。在这个简单的线程池实现中,我们可以通过`pthread_pool.cpp`、`MainFunctionForTest.cpp`、`...

    VC++ 线程池(ThreadPool)实现

    在编程领域,线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池在C++中是提高程序效率和资源管理的重要工具,尤其在处理大量并发操作时。本文将深入探讨VC++中...

    Java8并行流中自定义线程池操作示例

    Java8并行流中自定义线程池操作示例 Java8并行流中自定义线程池操作示例主要介绍了Java8并行流中自定义线程池操作,结合实例形式分析了并行流的相关概念、定义及自定义线程池的相关操作技巧。 1. 概览 Java8引入了...

    linux线程池创建c实现

    Linux 线程池创建 C 实现 线程池是一种常用的并发编程技术,它可以提高应用程序的性能和响应速度。在 Linux 系统中,使用 C 语言创建线程池可以实现高效的并发处理。 什么时候需要创建线程池呢?简单的说,如果一...

    DELPHI的ThreadPool的线程池DEMO

    DELPHI的线程池(ThreadPool)是一种高效管理并发任务的技术,它允许程序在需要时创建线程,而不是每次需要执行任务时都手动创建。线程池通过预先创建一组线程,然后根据需要分配任务,减少了线程创建和销毁的开销,...

    多线程写法(精易模块线程池和鱼刺模块线程池)

    本篇文章将重点探讨两种线程池实现:精易模块线程池和鱼刺模块线程池,并通过源码分析来展示它们的特点和用法。 首先,精易模块(SanYe Module)是由中国程序员SanYe开发的一系列开源模块,其中包含了线程池的实现...

    Linux线程池目录拷贝

    在Linux系统中,线程池是一种高效的进程管理方式,它允许多个任务并行执行,同时限制了系统中并发线程的数量,以优化资源分配和调度。本项目实现了利用线程池进行目录拷贝的功能,这涉及到多个重要的编程概念和技术...

    线程池管理多线程上传

    线程池管理和多线程上传是并发编程中的一个重要实践,特别是在大数据传输和网络服务中。在Java等编程语言中,线程池通过有效地管理和复用线程资源,避免了频繁创建和销毁线程带来的开销,提升了系统性能。下面将详细...

    仿ACE线程池机制实现的线程池类

    线程池是一种优化资源管理的机制,通过预先创建并维护一组可重用的线程,避免频繁地创建和销毁线程带来的性能开销。在Java、C++等编程语言中,线程池广泛应用于并发处理,提高系统效率,降低系统的资源消耗。本项目...

    Python 使用threading+Queue实现线程池示例

    一、线程池 1、为什么需要使用线程池 1.1 创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处理效率。 记创建线程消耗时间T1,执行任务消耗时间T2,销毁线程消耗时间T3,如果T1+T3&gt;T2,那...

    c++ 多线程线程池 demo

    线程池是多线程编程中一个重要的概念,它能够优化系统资源的使用,提高系统的响应速度和效率。本篇文章将深入探讨C++中的线程池实现,并通过名为“OEasyPool-1.0”的示例来展示其工作原理。 线程池是预先创建并维护...

    C#线程池 所有线程运行完毕

    在C#编程中,线程池(ThreadPool)是一种高效的线程管理机制,它允许开发者创建并管理多个线程,而无需直接操作线程对象。线程池中的线程可以复用,减少了创建和销毁线程的开销。当我们需要执行大量短生命周期的任务...

Global site tag (gtag.js) - Google Analytics