`
TimerBin
  • 浏览: 361127 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java ThreadPoolExecutor

    博客分类:
  • JAVA
阅读更多

java ThreadPoolExecutor 学习笔记

/**
  * @param corePoolSize
  *        线程池中保持的线程数量
  * @param maximumPoolSize
  *        线程池最大可开启线程数
  * @param keepAliveTime
  *        当线程池中的线程总量大于保持的线程数量时,
  *        此参数设置其中空闲的线程将保持的时间数量
  * @param unit
  *        保持的时间单位
  *        当其中的线程有空闲超过这个时间的,就将此线程杀死,
  *        一直到线程池的保持线程量,此时间设置将不再起作用
  * @param workQueue
  *        线程池的等待队列
  *        当需要执行的线程大于保持的线程数量时,会将此线程加入到这里设置的等待队列中
  * @param threadFactory
  *        线程工厂类 制定了此参数后可将Runnable实现类添加到execute方法中
  *        缺省使用静态内部类DefaultThreadFactory
  * @param handler
  *        当线程的等待队列超出容量时  执行的处理程序
  *        缺省使用静态内部类AbortPolicy
  */
  public ThreadPoolExecutor(
      int corePoolSize,
      int maximumPoolSize,
      long keepAliveTime,
      TimeUnit unit,
      BlockingQueue<Runnable> workQueue,
      ThreadFactory threadFactory,
      RejectedExecutionHandler handler){}

 一、简单案例

1、Executors.newFixedThreadPool(int num)

 特点:

固定线程池中可用线程数量,等待队列使用的是无界链表队列LinkedBlockingQueue,

源码:

 public static ExecutorService newFixedThreadPool(int nThreads) {
       return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
 }

简单例子如下所示:

public static void jdkExecutor(){
	ExecutorService exe = Executors.newFixedThreadPool(3);
	for(int i=0;i<5;i++){
		exe.execute(new Thread(new Runnable() {
			@Override
			public void run() {
			System.err.println(Thread.currentThread().getName());
			}
		}));
	}
}
//使用的是  线程的缺省 DefaultThreadFactory(静态内部类)线程工厂
public static void jdkExecutor2(){
	ExecutorService exe = Executors.newFixedThreadPool(3);
	for(int i=0;i<5;i++){
		exe.execute(new Runnable() {
			@Override
			public void run() {
			System.err.println(Thread.currentThread().getName());
			}
		});
	}
}
//自定义线程工厂
public static void jdkExecutor3(){
	ExecutorService exe = Executors.newFixedThreadPool(3,
        new JdkFactory());
	for(int i=0;i<5;i++){
		exe.execute(new Runnable() {
			@Override
			public void run() {
			System.err.println(Thread.currentThread().getName());
			}
		});
	}
}
//自定义工厂
public static class JdkFactory implements ThreadFactory{
	@Override
	public Thread newThread(Runnable r) {
		return new Thread( r);
	}
}

 运行结果如下所示(有三个线程在执行):

pool-1-thread-1
pool-1-thread-3
pool-1-thread-2
pool-1-thread-3
pool-1-thread-1

 2、Executors.newSingleThreadExecutor()

特点:

每一个任务都是使用同一个线程完成,等待队列使用的是无界链表队列LinkedBlockingQueue,

源码:

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
          (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
}

 简单例子如下所示:

 

public static void jdkExecutor(){
	ExecutorService exe = Executors.newSingleThreadExecutor();
	for(int i=0;i<5;i++){
		exe.execute(new Thread(new Runnable() {
			@Override
			public void run() {
		        System.err.println(Thread.currentThread().getName());
			}
	        }));
	}
}
//线程工厂模式同上

运行结果如下所示:

 

pool-1-thread-1
pool-1-thread-1
pool-1-thread-1
pool-1-thread-1
pool-1-thread-1

 

3、ExecutorService newCachedThreadPool()

特点:

线程池中可用线程数量无限,等待队列使用的是同步队列SynchronousQueue,会有60秒时间等待是否让空闲线程关闭。

源码:

 public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

 简单案例如下所示:

public static void jdkExecutor(){
	ExecutorService exe = Executors.newCachedThreadPool();
	for(int i=0;i<10;i++){
		exe.execute(new Thread(new Runnable() {
			@Override
			public void run() {
			System.err.println(Thread.currentThread().getName());
			}
		}));
	}
}
//线程工厂模式同上

 运行结果如下所示:

pool-1-thread-1
pool-1-thread-3
pool-1-thread-2
pool-1-thread-4
pool-1-thread-6
pool-1-thread-2
pool-1-thread-4
pool-1-thread-3
pool-1-thread-6
pool-1-thread-5

 4、直接使用JDK ThreadPoolExecutor

 简单案例如下所示:

public static void jdkBaseExecuter(){
	ThreadPoolExecutor treadepool = new ThreadPoolExecutor(2, 4,60,
        TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(200),
        new ErrorHandler());
	for(int i=0;i<10;i++){
		treadepool.execute(new Runnable() {
			@Override
			public void run() {
			   System.err.println(Thread.currentThread().getName());
			}
		});
	}
}
//RejectedExecutionHandler缺省使用内部类AbortPolicy
private static class ErrorHandler implements RejectedExecutionHandler{
	@Override
	public void rejectedExecution(Runnable r,ThreadPoolExecutor executor) {
		System.err.println("队列越界:"+executor.getQueue().size());
	}
}

 运行结果如下所示:

pool-1-thread-1
pool-1-thread-2
pool-1-thread-1
pool-1-thread-2
pool-1-thread-1
pool-1-thread-2
pool-1-thread-2
pool-1-thread-2
pool-1-thread-1
pool-1-thread-2

 发现此时程序一直使用的是2个线程再执行任务,并未对保持线程数进行扩充。原因是因为此时有界缓存队列大小为200,未达到队列最大值,并不会重新开启新线程。将代码做如下改动:

ThreadPoolExecutor treadepool = new ThreadPoolExecutor(2, 4,60,
TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(6),new ErrorHandler());

 运行结果将如下所示:

pool-1-thread-1
pool-1-thread-3
pool-1-thread-3
pool-1-thread-3
pool-1-thread-2
pool-1-thread-2
pool-1-thread-2
pool-1-thread-3
pool-1-thread-4
pool-1-thread-1

 如果将有界队列值再缩小如下所示:

ThreadPoolExecutor treadepool = new ThreadPoolExecutor(2, 4,60,
TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(4),new ErrorHandler());

 运行结果如下所示:

pool-1-thread-1
pool-1-thread-3
pool-1-thread-4
队列越界:4
pool-1-thread-2
pool-1-thread-4
pool-1-thread-4
pool-1-thread-3
pool-1-thread-1
pool-1-thread-2

 就会出现队列越界错误,如果使用的是缺省ExecutionHandler将会初夏如下错误:

java.util.concurrent.RejectedExecutionException: 
Task xxxxxxx rejected from java.util.concurrent.ThreadPoolExecutor@56833a2e
[Running, pool size = 4, active threads = 0, queued tasks = 0, completed tasks = 8]
	at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2048)
	at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:821)
	at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1372)
 

 所以对线程池的配置要慎重。

5、ThreadPoolTaskExecutor spring线程池

简单案例如下所示:

public static void springExecutor(){
	ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        //手动创建时需要进行初始化ThreadFactory 和RejectedExecutionHandler
	taskExecutor.initialize();
	taskExecutor.setCorePoolSize(2);
	taskExecutor.setMaxPoolSize(4);
	taskExecutor.setQueueCapacity(200);
	for(int i=0;i<10;i++){
		taskExecutor.execute(new Thread(new Runnable() {		
			@Override
			public void run() {
				System.err.println(Thread.currentThread().getName());
			}
		}));
	}
}

 当然ThreadPoolTaskExecutor 也可以在Spring的XML中进行定义,然后依赖注入进来,代码如下所示:

@Autowired
private TaskExecutor taskExecutor;
<bean id="taskExecutor" class=
"org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
		<property name="corePoolSize" value="2" />
		<property name="maxPoolSize" value="4" />
		<property name="queueCapacity" value="200" />
</bean>
注:在基于Spring容器时不需要手工进行initialize初始化,交由Spring容器初始化

 运行结果如下所示:

ThreadPoolTaskExecutor-1
ThreadPoolTaskExecutor-1
ThreadPoolTaskExecutor-1
ThreadPoolTaskExecutor-1
ThreadPoolTaskExecutor-2
ThreadPoolTaskExecutor-1
ThreadPoolTaskExecutor-2
ThreadPoolTaskExecutor-1
ThreadPoolTaskExecutor-2
ThreadPoolTaskExecutor-1

 具体的参数配置同上

 注:以上的各种队列的不同点将于下篇进行说明

 

 

 

 

 

分享到:
评论

相关推荐

    java ThreadPoolExecutor 并发调用实例详解

    java ThreadPoolExecutor 并发调用实例详解 java 中的并发编程是指在多个线程中执行多个任务,以提高程序的执行效率。在 Java 中,有多种方式可以实现并发编程,包括使用 Thread、Runnable、Callable、Future、...

    java ThreadPoolExecutor使用方法简单介绍

    主要介绍了java ThreadPoolExecutor使用方法简单介绍的相关资料,需要的朋友可以参考下

    Java ThreadPoolExecutor 线程池的使用介绍

    提供工厂方法来创建不同类型的线程池,这篇文章主要介绍了Java ThreadPoolExecutor 线程池的使用介绍,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来...

    Java ThreadPoolExecutor的参数深入理解

    Java ThreadPoolExecutor参数深入理解 Java ThreadPoolExecutor是Java并发编程中一个非常重要的组件,它提供了一种灵活的方式来管理线程池。ThreadPoolExecutor的参数深入理解是Java开发人员需要掌握的重要知识点,...

    ThreadPoolExecutor使用和思考

    ThreadPoolExecutor使用和思考

    java 线程池例子ThreadPoolExecutor

    Java 线程池例子 ThreadPoolExecutor Java 中的线程池是指一个容器,里面包含了多个线程,这些线程可以重复使用,以避免频繁创建和销毁线程的开销。ThreadPoolExecutor 是 Java 中一个非常重要的线程池实现类,它...

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

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

    线程池:java_ThreadPoolExecutor.mht

    (转)线程池:java_util_ThreadPoolExecutor 比较详细的介绍了ThreadPoolExecutor用法与属性

    Java多线程Executors批量执行数据实现限流

    Java多线程实现数据切割批量执行,实现限流操作。 java线程池Executors实现数据批量操作。 批量异步Executors处理数据,实现限流操作,QPS限流。 线程池调用第三方接口限流实现逻辑。 案例适合: 1.批量处理大数据。...

    redis lits queue 和 ThreadPoolExecutor 结合

    在IT行业中,Redis和Java的ThreadPoolExecutor是两个非常重要的工具,它们在处理高并发和任务调度方面发挥着关键作用。Redis是一种高效的键值存储系统,常用于缓存、消息队列等场景。而ThreadPoolExecutor是Java并发...

    java实现的模拟ping功能

    ### Java实现的模拟Ping功能详解 #### 一、概述 在计算机网络中,Ping命令是一种常用的测试工具,用于检查网络连接是否可用,并测量与远程主机的往返时间。本篇文章将详细解析一个用Java语言编写的模拟Ping功能的...

    java 四种线程池实例

    本文将深入探讨四种常见的Java线程池实例:`ThreadPoolExecutor`、`Executors`提供的固定线程池、单线程池和定时线程池。 1. **ThreadPoolExecutor**: 这是最基础也是最灵活的线程池实现,可以通过`new ...

    Java线程池ThreadPoolExecutor原理及使用实例

    Java线程池ThreadPoolExecutor原理及使用实例 Java线程池ThreadPoolExecutor是Java并发编程中的一种基本机制,主要用于管理和执行任务的线程池。下面对其原理和使用实例进行详细介绍。 线程池概述 线程池是一个...

    java中Executor,ExecutorService,ThreadPoolExecutor详解

    主要介绍了java中Executor,ExecutorService,ThreadPoolExecutor详解的相关资料,需要的朋友可以参考下

    java线程池ThreadPoolExecutor类使用详解.docx

    在《阿里巴巴java开发手册》中指出了线程资源必须通过线程池提供,不允许在应用中自行显示的创建线程,这样一方面是线程的创建更加规范,可以合理控制开辟线程的数量;另一方面线程的细节管理交给线程池处理,优化了...

    Java 5_0 多线程编程实践

    ### Java 5.0 多线程编程实践 在Java 5.0版本中,多线程编程得到了显著增强,特别是在引入了`java.util.concurrent`包之后,为开发者提供了更为丰富的API来处理并发问题。本篇文章将深入探讨如何在Java 5.0中有效地...

    Java线程池与ThreadPoolExecutor.pdf

    Java线程池是Java并发编程中...总结来说,理解并正确使用Java线程池和ThreadPoolExecutor对于优化Java应用程序的并发性能至关重要。通过调整线程池的参数,可以平衡资源利用率和系统响应时间,从而提高整体的系统效率。

    JDK1.5中的线程池(java.util.concurrent.ThreadPoolExecutor)使用

    "JDK1.5中的线程池(java.util.concurrent.ThreadPoolExecutor)使用" JDK1.5中的线程池(java.util.concurrent.ThreadPoolExecutor)使用是Java多线程编程中的一种重要概念。随着多线程编程的普及,线程池的使用变得...

    线程池Demo(待续)

    在Java中,`java.util.concurrent`包提供了线程池的实现,如`ExecutorService`、`ThreadPoolExecutor`等。下面将详细解释线程池的工作原理及其在`Test.java`、`TestThread.java`、`TestThreadPool.java`这些文件中的...

    线程池简单实现chenjiegui

    在Java中,线程池是通过`java.util.concurrent`包中的`ExecutorService`接口及其实现类来实现的,如`ThreadPoolExecutor`。下面我们将深入探讨线程池的工作原理、核心参数以及如何在实际开发中使用线程池。 线程池...

Global site tag (gtag.js) - Google Analytics