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

线程池

 
阅读更多

线程池在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后,就会把到达的任务放到缓存队列当中; ...

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

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

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

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

    线程池  

    VC实现线程池

    易语言真正的线程池简易实现

    易语言简易线程池的实现。 ——V雪落有声V原创。转载请保留。前文:。为了能充分理解本篇文章的内容,需要了解的知识如下:。1.事件对象的使用:http://baike.baidu.com/view/751499.htm。2.信号量的使用:...

    Java简单线程池 线程池中文文档

    简单的线程池程序+中文文档 包结构: com.tangkai.threadpool --SimpleThread.java 工作线程 --TestThreadPool.java 程序入口 --ThreadPoolManager.java 线程池管理类

    Windows下一个比较完美的线程池实现和示例

    Windows下一个比较完美的线程池实现和示例 本线程池提供了如下功能: 1.能根据任务个数和当前线程的多少在最小/最大线程个数之间自动调整(Vista后的系统有 SetThreadpoolThreadMaximum 等函数有类似功能); 2.能方便...

    C#管理线程池的类ThreadManager

    C#管理线程池的类 /* How to use Thread Classs * * ============== * public ELMService() { InitializeComponent(); etm.ClalThreadPool("EmailThreads", (uint)ApplicationInfo.EmailParsingThreads); ...

    线程池.zip,互斥锁+条件变量+队列,实现线程池,包括线程池的创建,塞任务,和销毁线程池

    线程池

    易语言线程池操作例程(解决内存不断升高的问题)

     因为本人是个小白,多线程经常用,但是线程池并没有用过,(一听到线程池,总感觉高大上)。但是近期写彩票软件的时候发现,多线程长期操作会导致内容不断的升高直至报错,遂想起了线程池,完善后发现不是一般的叼...

    一个通用的Java线程池类

    2.然后根据提示运行java命令执行示例程序,观看线程池的运行结果 目标:Java中多线程技术是一个难点,但是也是一个核心技术。因为Java本身就是一个多线程语言。本人目前在给46班讲授Swing的网络编程--使用Swing来...

    VC简单的线程池使用实例

    1.线程池管理器(ThreadPoolManager):用于创建并管理线程池 2.工作线程(WorkThread): 线程池中线程 3.任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行。 4.任务队列:用于存放没有处理的...

    如何使用线程池

    以下示例显示如何使用线程池。首先创建 ManualResetEvent 对象,此对象使程序能够知道线程池何时运行完所有的工作项。接着,尝试向线程池添加一个线程。如果添加成功,则添加其余的线程(本例中为 4 个)。然后...

    linux线程池创建c实现

    linux线程池创建c实现 linux线程池创建c实现 linux线程池创建c实现 linux线程池创建c实现 linux线程池创建c实现 linux线程池创建c实现

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

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

    Linux下通用线程池的构建

    什么是线程池?简单点说,线程池就是有一堆已经创建好了的线程,初始它们都处于空闲等待状态,当有新的任务需要处理的时候,就从这个池子里面取一个空闲等待的线程来处理该任务,当处理完成了就再次把该线程放回池中...

    一个简单线程池的实现

    这是一个简单线程池的实现,虽然有很多bug,但是能够简单地实现线程池。

    Java 自己实现线程池

    Java开发,Android开发,自己实现线程池,明白线程池的实现机制

    jdbc线程池演示demo

    本实例采用c3p0作为线程池工具包,讲解了jdbc基本用法,同时给出了Oracle以及mysql增(单插入、批量插入)、删、查、改等功能,可以直接复制使用。

Global site tag (gtag.js) - Google Analytics