线程池ThreadPoolExecutor运用简介sina - 凯发娱乐

线程池ThreadPoolExecutor运用简介sina

2018-11-10 07:52:39 | 作者: 向山 | 标签: 线程,运用,行列 | 浏览: 480



转载地址:https://coach.iteye.com/blog/855850

一、简介
线程池类为 java.util.concurrent.ThreadPoolExecutor,常用结构办法为:

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue Runnable workQueue,
RejectedExecutionHandler handler)
corePoolSize: 线程池保护线程的最少数量
maximumPoolSize:线程池保护线程的最大数量
keepAliveTime: 线程池保护线程所答应的闲暇时刻
unit: 线程池保护线程所答应的闲暇时刻的单位
workQueue: 线程池所运用的缓冲行列
handler: 线程池对回绝使命的处理战略

一个使命经过 execute(Runnable)办法被增加到线程池,使命就是一个 Runnable类型的目标,使命的履行办法就是 Runnable类型目标的run()办法。

当一个使命经过execute(Runnable)办法欲增加到线程池时:
a、假如此刻线程池中的数量小于corePoolSize,即便线程池中的线程都处于闲暇状况,也要创立新的线程来处理被增加的使命。
b、假如此刻线程池中的数量等于 corePoolSize,可是缓冲行列 workQueue未满,那么使命被放入缓冲行列。
c、假如此刻线程池中的数量大于corePoolSize,缓冲行列workQueue满,而且线程池中的数量小于maximumPoolSize,建新的线程来处理被增加的使命。
d、假如此刻线程池中的数量大于corePoolSize,缓冲行列workQueue满,而且线程池中的数量等于maximumPoolSize,那么经过 handler所指定的战略来处理此使命。

处理使命的优先级为:
中心线程corePoolSize、使命行列workQueue、最大线程maximumPoolSize,假如三者都满了,运用handler处理被回绝的使命。

当线程池中的线程数量大于 corePoolSize时,假如某线程闲暇时刻超越keepAliveTime,线程将被停止。这样,线程池能够动态的调整池中的线程数。

unit可选的参数为java.util.concurrent.TimeUnit中的几个静态特点:
NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS。

workQueue我常用的是:java.util.concurrent.ArrayBlockingQueue

handler有四个挑选:
ThreadPoolExecutor.AbortPolicy()
抛出java.util.concurrent.RejectedExecutionException反常
ThreadPoolExecutor.CallerRunsPolicy()
重试增加当时的使命,他会主动重复调用execute()办法
ThreadPoolExecutor.DiscardOldestPolicy()
扔掉旧的使命
ThreadPoolExecutor.DiscardPolicy()
扔掉当时的使命

二、一般用法举例
 package demo; 
 import java.io.Serializable; 
 import java.util.concurrent.ArrayBlockingQueue; 
 import java.util.concurrent.ThreadPoolExecutor; 
 import java.util.concurrent.TimeUnit; 
 public class TestThreadPool2 
 private static int produceTaskSleepTime = 2; 
 private static int produceTaskMaxNumber = 10; 
 public static void main(String[] args) 
 // 结构一个线程池 
 ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 3, TimeUnit.SECONDS, new ArrayBlockingQueue Runnable (3), 
 new ThreadPoolExecutor.DiscardOldestPolicy()); 
 for (int i = 1; i = produceTaskMaxNumber; i++) 
 try 
 // 发生一个使命,并将其加入到线程池 
 String task = "task@ " + i; 
 System.out.println("put " + task); 
 threadPool.execute(new ThreadPoolTask(task)); 
 // 便于调查,等候一段时刻 
 Thread.sleep(produceTaskSleepTime); 
 catch (Exception e) 
 e.printStackTrace(); 
 /** 
 * 线程池履行的使命 
 class ThreadPoolTask implements Runnable, Serializable 
 private static final long serialVersionUID = 0; 
 private static int consumeTaskSleepTime = 2000; 
 // 保存使命所需求的数据 
 private Object threadPoolTaskData; 
 ThreadPoolTask(Object tasks) 
 this.threadPoolTaskData = tasks; 
 public void run() 
 // 处理一个使命,这儿的处理方式太简略了,仅仅是一个打印句子 
 System.out.println(Thread.currentThread().getName()); 
 System.out.println("start .." + threadPoolTaskData); 
 try 
 // //便于调查,等候一段时刻 
 Thread.sleep(consumeTaskSleepTime); 
 catch (Exception e) 
 e.printStackTrace(); 
 threadPoolTaskData = null; 
 public Object getTask() 
 return this.threadPoolTaskData; 
 } 



阐明:
1、在这段程序中,一个使命就是一个Runnable类型的目标,也就是一个ThreadPoolTask类型的目标。
2、一般来说使命除了处理方式外,还需求处理的数据,处理的数据经过结构办法传给使命。
3、在这段程序中,main()办法相当于一个残暴的领导,他派宣布许多使命,丢给一个叫 threadPool的勤勤恳恳的小组来做。
这个小组里边队员至少有两个,假如他们两个忙不过来,使命就被放到使命列表里边。
假如积压的使命过多,多到使命列表都装不下(超越3个)的时分,就雇佣新的队员来协助。可是依据本钱的考虑,不能雇佣太多的队员,至多只能雇佣 4个。
假如四个队员都在忙时,再有新的使命,这个小组就处理不了了,使命就会被经过一种战略来处理,咱们的处理方式是不断的派发,直到承受这个使命停止(更残暴!呵呵)。
由于队员作业是需求本钱的,假如作业很闲,闲到 3SECONDS都没有新的使命了,那么有的队员就会被辞退了,可是,为了小组的正常作业,即便作业再闲,小组的队员也不能少于两个。
4、经过调整 produceTaskSleepTime和 consumeTaskSleepTime的巨细来完成对派发使命和处理使命的速度的操控,改动这两个值就能够调查不同速率下程序的作业情况。
5、经过调整4中所指的数据,再加上调整使命丢掉战略,换上其他三种战略,就能够看出不同战略下的不同处理方式。
6、关于其他的运用办法,参看jdk的协助,很简单了解和运用。


另一个比如:
 package demo; 
 import java.util.Queue; 
 import java.util.concurrent.ArrayBlockingQueue; 
 import java.util.concurrent.ThreadPoolExecutor; 
 import java.util.concurrent.TimeUnit; 
 public class ThreadPoolExecutorTest 
 private static int queueDeep = 4; 
 public void createThreadPool() 
 * 创立线程池,最小线程数为2,最大线程数为4,线程池保护线程的闲暇时刻为3秒, 
 * 运用行列深度为4的有界行列,假如履行程序没有封闭,则坐落作业行列头部的使命将被删去, 
 * 然后重试履行程序(假如再次失利,则重复此进程),里边现已依据行列深度对使命加载进行了操控。 
 ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 4, 3, TimeUnit.SECONDS, new ArrayBlockingQueue Runnable (queueDeep), 
 new ThreadPoolExecutor.DiscardOldestPolicy()); 
 // 向线程池中增加 10 个使命 
 for (int i = 0; i i++) 
 try 
 Thread.sleep(1); 
 catch (InterruptedException e) 
 e.printStackTrace(); 
 while (getQueueSize(tpe.getQueue()) = queueDeep) 
 System.out.println("行列已满,等3秒再增加使命"); 
 try 
 Thread.sleep(3000); 
 catch (InterruptedException e) 
 e.printStackTrace(); 
 TaskThreadPool ttp = new TaskThreadPool(i); 
 System.out.println("put i:" + i); 
 tpe.execute(ttp); 
 tpe.shutdown(); 
 private synchronized int getQueueSize(Queue queue) 
 return queue.size(); 
 public static void main(String[] args) 
 ThreadPoolExecutorTest test = new ThreadPoolExecutorTest(); 
 test.createThreadPool(); 
 class TaskThreadPool implements Runnable 
 private int index; 
 public TaskThreadPool(int index) 
 this.index = index; 
 public void run() 
 System.out.println(Thread.currentThread() + " index:" + index); 
 try 
 Thread.sleep(3000); 
 catch (InterruptedException e) 
 e.printStackTrace(); 
 } 

版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表凯发娱乐立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章

阅读排行

  • 1
  • 2
  • 3

    rails 对 URL的一些处理sina

    办法,途径,地址
  • 4
  • 5
  • 6

    Obsolete特点sohu

    特点,正告,运用
  • 7
  • 8

    JAVA根底 之 JDBCITeyetengxun

    数据库,根底,运用
  • 9
  • 10