Java线程池工具类

使用线程池的好处:

  1. 重用线程,线程的创建和销毁是很耗时的。
  2. 控制线程的数量。

线程池工具类:

ThreadPool.java

package com.zws.thread.pool;

import java.util.concurrent.Callable;
import java.util.concurrent.Future;
/**
 * 
 * @author wensh.zhu
 *
 */
public interface ThreadPool {

	void execute(Runnable task);

	<T> Future<T> submit(Callable<T> task);

	/**
	 * 线程池是否繁忙
	 * @return
	 */
	boolean isBusy();
}

SimpleThreadPool.java

package com.zws.thread.pool;

import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
 * 
 * @author wensh.zhu
 *
 */
public class SimpleThreadPool implements ThreadPool{

	private static int corePoolSize = 30, maximumPoolSize = 50, capacity = 50000;
	private static long keepAliveTime = 30 * 1000l;
	private static LinkedBlockingQueue<Runnable> workQueue;

	private static ThreadPoolExecutor executor;

	private static SimpleThreadPool pool = new SimpleThreadPool();

	private SimpleThreadPool() {
		workQueue = new LinkedBlockingQueue<Runnable>(capacity);
		executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, 
				TimeUnit.MILLISECONDS, workQueue, new RejectionHandler());
	}

	public static SimpleThreadPool newInstance() {
		return pool;
	}

	public void execute(Runnable task) {
		executor.execute(task);
	}

	public <T> Future<T> submit(Callable<T> task) {
		return executor.submit(task);
	}

	public boolean isQueueFull() {
		return workQueue.size() == capacity;
	}

	public int queueSize() {
		return workQueue.size();
	}

	public boolean isBusy() {
		return executor.getPoolSize() == maximumPoolSize && isQueueFull();
	}

	public int poolSize() {
		return executor.getPoolSize();
	}

}

RejectionHandler.java

package com.zws.thread.pool;

import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
/**
 * 
 * @author wensh.zhu
 *
 */
public class RejectionHandler implements RejectedExecutionHandler {

	@Override
	public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
		System.out.println("task " + r + " execute fail");

	}
}

解释ThreadPoolExecutor类构造函数的参数:

corePoolSize:核心线程数,线程池保有的线程的数量,如果allowCoreThreadTimeOut 参数不设置,即使这些线程空闲也不会被回收。也就是说如果allowCoreThreadTimeOut 参数不设置那么当线程池内的线程的数量升至大于等于corePoolSize后,线程池至少会保有corePoolSize数量的线程。

workQueue:线程池工作队列,当线程池内线程的数量达到corePoolSize并且这些线程都处于忙碌状态时,那么后续提交至线程池的任务会被缓存至工作队列中,当线程池内有空闲线程时就会从此工作队列中取任务并执行。

maximumPoolSize:线程池所允许的最大线程的数量,当工作队列满时,线程池会继续创建新的线程,但是线程池内总线程数量不会超过maximumPoolSize。

keepAliveTime:当线程池内线程的数量超过corePoolSize时,超出部分线程的空闲等待时间,当空闲时间超过此值则超出部分线程就会被回收。

unit:keepAliveTime的单位。

handler:线程池任务拒绝策略接口,当工作队列满并且线程池忙碌线程数量达到maximumPoolSize后,后续提交至线程池的任务会被拒绝,此时回调此接口,自己实现具体的拒绝策略。如果此接口没有指定则报java.util.concurrent.RejectedExecutionException异常。

时间: 2024-10-28 13:23:29

Java线程池工具类的相关文章

java 线程池管理类:Executors

java.util.concurrent类 Executors java.lang.Object   继承者 java.util.concurrent.Executors此类是个工具类,它提供对Executor.ExecutorService.ScheduledExecutorService.ThreadFactory 和 Callable 类的一些实用方法. 此类支持以下各种方法:    * 创建并返回设置有常用配置的ExecutorService的方法.    * 创建并返回设置有常用配置的

java线程池ThreadPoolExecutor类使用详解

在<阿里巴巴java开发手册>中指出了线程资源必须通过线程池提供,不允许在应用中自行显示的创建线程,这样一方面是线程的创建更加规范,可以合理控制开辟线程的数量:另一方面线程的细节管理交给线程池处理,优化了资源的开销.而线程池不允许使用Executors去创建,而要通过ThreadPoolExecutor方式,这一方面是由于jdk中Executor框架虽然提供了如newFixedThreadPool().newSingleThreadExecutor().newCachedThreadPool(

java 线程池 ---- ThreadPoolExecutor 类

执行流程 1, 创建线程池后, 默认不会创建线程, 等到有任务带来才创建线程, 即一个线程处理一个任务 2, 当线程数量达到核心线程数时, 任务放进队列, 如果放入队列失败, 创建新线程处理任务(此时线程池线程数大于核心线程数) 3, 如果线程数大于最大线程数, 执行拒绝策略处理任务 构造方法 public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, Block

JAVA 并发编程-线程同步工具类(十二)

本文主要介绍一些java线程同步工具类,并不进行具体讲解,当有需要时,可以再去结合实例学习. 信号灯(Semaphore) 应用场景举例: 例如公司的打卡系统,如果有一个打卡机,那么一次就只能有一个人打卡,其余的人就被阻塞住,打卡完以后就可由下一个人打卡.如果有3个打卡机,那么一次就允许3个人或者少于三个人打卡,其余的人就得等待打卡机空闲下来才能继续打卡. 结果: 已进入1个线程,还可进入2个 已进入2个线程,还可进入1个 已进入3个线程,还可进入0个 空余出1个 已进入4个线程,还可进入0个

Java 线程池原理分析

1.简介 线程池可以简单看做是一组线程的集合,通过使用线程池,我们可以方便的复用线程,避免了频繁创建和销毁线程所带来的开销.在应用上,线程池可应用在后端相关服务中.比如 Web 服务器,数据库服务器等.以 Web 服务器为例,假如 Web 服务器会收到大量短时的 HTTP 请求,如果此时我们简单的为每个 HTTP 请求创建一个处理线程,那么服务器的资源将会很快被耗尽.当然我们也可以自己去管理并复用已创建的线程,以限制资源的消耗量,但这样会使用程序的逻辑变复杂.好在,幸运的是,我们不必那样做.在

java线程池监控

原因 最近在完善公司的基础发布平台的时候,使用到了一线程去做一些异步的事情,在开发环境和测试环境验证没有任何问题,但是在程序在生产运行一段时间后,发现没有得到自己想要的结果,为此开始了漫长的排查bug的之路,因为用到了一些线程,但是实际又没有对这些线程足够的监控,所以在排查问题的时候也是历经艰难险阻: 原始代码 protected ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2); /**

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

刚刚研究了一下线程池,如果有不足之处,请大家不吝赐教,大家共同学习.共同交流. 在什么情况下使用线程池? 单个任务处理的时间比较短 将需处理的任务的数量大 使用线程池的好处: 减少在创建和销毁线程上所花的时间以及系统资源的开销 如不使用线程池,有可能造成系统创建大量线程而导致消耗完系统内存以及"过度切换". 线程池工作原理: 为什么要用线程池? 诸如 Web 服务器.数据库服务器.文件服务器或邮件服务器之类的许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务.请求以某种方式到

Java多线程——线程阻塞工具类LockSupport

简述 LockSupport 是一个非常方便实用的线程阻塞工具,它可以在线程内任意位置让线程阻塞. 和 Thread.suspend()相比,它弥补了由于 resume()在前发生,导致线程无法继续执行的情况. 和 Object.wait()相比,它不需要先获得某个对象的锁,也不会抛出 InterruptedException 异常. LockSupport 的静态方法 park()可以阻塞当前线程,类似的还有 parkNanos().parkUntil()等方法.它们实现了一个限时等待,如下图

Java线程池应用

Executors工具类用于创建Java线程池和定时器. newFixedThreadPool:创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程.在任意点,在大多数 nThreads 线程会处于处理任务的活动状态.如果在所有线程处于活动状态时提交附加任务,则在有可用线程之前,附加任务将在队列中等待.如果在关闭前的执行期间由于失败而导致任何线程终止,那么一个新线程将代替它执行后续的任务(如果需要).在某个线程被显式地关闭之前,池中的线程将一直存在. 创建一个固定大小的线程池来执