线程池浅析

线程池顾名思义就是放线程的池子 Thread Pool。

那么为什么要有线程池呢?有些时候系统需要处理非常多的执行时间很短的请求,如果每一个请求都开启一个新的线程,则系统创建销毁线程的开销就太大了,甚至在创建和销毁线程的时间比任务的执行时间还长。

使用new Thread() 会有如下缺点:

1.创建和销毁线程耗费大量系统资源;

2.每次new Thread() 缺乏线程管理,被称为野线程,而且可以无限制创建,之间相互竞争,会导致过多占用系统资源导致系统瘫痪。

3.不利于扩展,如定期执行,定时执行,线程中断。

线程池主要解决了两个问题:

1.通过重用线程,达到减少每个线程创建和销毁的性能开销。

2.对线程进行一些维护,比如定时开始,周期执行,并发控制等。

3.可控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争。

Executor:JDK1.5引入,内部使用线程池机制,在java.util.cocurrent包下,Executor框架包括:线程池,Executor,Executors,ExecutorService,CompletionService,Future,Callable,ThreadPoolExecutor等。

Executors:工厂类 创建线程池

1.newFixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads) {

    return new ThreadPoolExecutor(nThreads, nThreads,

                                  0L, TimeUnit.MILLISECONDS,

                                  new LinkedBlockingQueue<Runnable>());

}

创建一个固定数目的线程池,内部维持一个无界的队列,当所有的线程都在处于活动状态时提交了其他任务,则新任务将在队列中等待直到线程可用。

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

创建一个根据需要创建新线程的线程池,但在可用时将重新使用以前构造的线程。

该线程池适用于执行许多短暂异步任务的程序,调用execute会重用以前构造的线程,如果没有可用的线程,则会创建新的线程,并将该线程添加到该池中,未使用60秒的线程将被终止并从缓存中删除。因此,长时间保持闲置的池将不会消耗任何资源。

3.newSingleThreadExecutor
public static ExecutorService newSingleThreadExecutor() {

    return new FinalizableDelegatedExecutorService

        (new ThreadPoolExecutor(1, 1,

                                0L, TimeUnit.MILLISECONDS,

                                new LinkedBlockingQueue<Runnable>()));

}

创建一个使用无界队列运行单个工作线程的执行程序,等效于newFixedThreadPool(1)

4.newScheduledThreadPool
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {

    return new ScheduledThreadPoolExecutor(corePoolSize);

}

创建一个线程池,可以调度命令在给定的延迟之后运行,或定期执行。

scheduleAtFixedRate(Runnable command,
                                                 long initialDelay,
                                                 long delay,
                                                 TimeUnit unit);

首次执行在 initialDelay 之后,第二次 执行时间为 initialDelay+delay*1 ….

scheduleWithFixedDelay(Runnable command,
                                                 long initialDelay,
                                                 long delay,
                                                 TimeUnit unit);

第一次的执行时间为 当前时间+ initialDelay,第二次为第一次执行结束时间+delay

ExecutorService 的submit() 和 execute()区别:

1.入参不同 submit可以接收Runnable或者Callable ,execute方法只能接收Runnable

2.返回值 submit 有返回值 而 execute没有返回值

3.submit方便处理Exception  Future.get抛出的异常

Runnable和Callable的区别

Callable接口中的call方法是有返回值的,泛型可任意制定,但是Runnable接口中run方法是没有返回值的。

ThreadPoolExecutor:JDK提供的Executors工具类中创建的线程无法满足使用场景时,则需要手动配置和调优,则用到该池。

public ThreadPoolExecutor(int corePoolSize,

                          int maximumPoolSize,

                          long keepAliveTime,

                          TimeUnit unit,

                          BlockingQueue<Runnable> workQueue) {

    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,

         Executors.defaultThreadFactory(), defaultHandler);

}

参数详解:

corePoolSize:核心线程数

maximumPoolSize:最大线程数

keepAliveTime:最大空闲时间

BlockingQueue:使用的任务队列

ArrayBlockingQueue:底层是数组的定长任务队列,必须制定长度,可设置是               否公平锁。默认先进先出

LinkedBlockingQueue:底层为链表的可定长任务队列,不指定长度则为无界,             可设置公平锁,默认为先进先出

SynchronousQueue:同步的没有缓冲的任务队列,只有当线程将队列中的take走之后,才能新加进来任务

defaultHandler:该参数代表的是拒绝策略,默认为AbortPolicy

可以通过设置改变

/**
 * ThreadPoolExecutor.AbortPolicy() 
抛出java.util.concurrent.RejectedExecutionException异常
 
* ThreadPoolExecutor.CallerRunsPolicy() 使用主线程跑当前任务
 
* ThreadPoolExecutor.DiscardOldestPolicy() 抛弃旧的任务
 
* ThreadPoolExecutor.DiscardPolicy() 抛弃当前的任务
 
*/

ThreadPool study的更多相关文章

  1. ThreadPool.QueueUserWorkItem的用法

    代码: ThreadPool.SetMaxThreads(, ); ThreadPool.QueueUserWorkItem((obj) => { MessageBox.Show("执 ...

  2. C# - 多线程 之 Process与Thread与ThreadPool

    Process 进程类, // 提供对本地和远程进程的访问,启动/停止本地系统进程 public class Process : Component { public int Id { get; } ...

  3. C#多线程--线程池(ThreadPool)

    先引入一下线程池的概念: 百度百科:线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池线程都是后台线程.每个线程都使用默认的堆栈大小,以默认的优先级运行, ...

  4. mysql can't create threads in threadpool

    最近,我们在券商端的mysql运行一段时间后,发生mysql can't create threads in threadpool,如下所示: 据官网一个报告显示,目测是一个bug,内存紧张导致,那天 ...

  5. Nodejs事件引擎libuv源码剖析之:高效线程池(threadpool)的实现

    声明:本文为原创博文,转载请注明出处. Nodejs编程是全异步的,这就意味着我们不必每次都阻塞等待该次操作的结果,而事件完成(就绪)时会主动回调通知我们.在网络编程中,一般都是基于Reactor线程 ...

  6. Improve Your Study Habits

    1.Plan your time carefully. Make a list of your weekly tasks.Then make a schedule or chart of your t ...

  7. C#中Thread与ThreadPool的比较

    最近同事在编写一个基于UPD RTP协议的通信软件,在处理接收Listen时,发现了一个问题到底是用Thread还是ThreadPool呢? 我看同事的问题比较有典型性,还是做以整理培训一下吧 Thr ...

  8. python线程池(threadpool)模块使用笔记

    一.安装与简介 pip install threadpool pool = ThreadPool(poolsize) requests = makeRequests(some_callable, li ...

  9. Thread and ThreadPool

    C#中Thread与ThreadPool的比较 Thread类,一次使用一个线程,来创建和删除线程.这种方式建立和删除线程是很昂贵的(cpu密集型). Threadpool类 对于大多数的情况下是使用 ...

随机推荐

  1. 集群安装Java环境

    需要安装一个集群环境,发现全部要手动安装java.记录下安装Java环境的过程.虽然,依旧是挨个安装,但总算是有体系了. java 找到下载地址: https://www.oracle.com/tec ...

  2. SSE图像算法优化系列二十五:二值图像的Euclidean distance map(EDM)特征图计算及其优化。

    Euclidean distance map(EDM)这个概念可能听过的人也很少,其主要是用在二值图像中,作为一个很有效的中间处理手段存在.一般的处理都是将灰度图处理成二值图或者一个二值图处理成另外一 ...

  3. quartz集群分布式(并发)部署解决方案

    项目中使用分布式并发部署定时任务,多台跨JVM,按照常理逻辑每个JVM的定时任务会各自运行,这样就会存在问题,多台分布式JVM机器的应用服务同时干活,一个是加重服务负担,另外一个是存在严重的逻辑问题, ...

  4. [android警告]AndroidManifest.xml警告 Not targeting the latest versions of Android

    警告:Not targeting the latest versions of Android; compatibility modes apply.Consider testing and upda ...

  5. iOS/MAC 数据压缩与解压缩及常用算法 LZMA、ZLIB

    苹果提供的常用的数据压缩算法LZMA.ZLIB.LZ4等: 这三种算法也是苹果建议的,可跨平台使用: 定义如下: /* Commonly-available encoders */ COMPRESSI ...

  6. 魔术方法__get()、__set()和__call()的用法

    刚开始学习魔术方法时对__get().__set() 和__call()的用法和作用不是太了解,也有一些误解... 现在分享一下个人的理解,大家共勉一下: __get().__set() 和__cal ...

  7. iOS开发小技巧 - UILabel添加中划线

    iOS开发小技巧 遇到的问题: 给Label添加中划线,然后并没有效果 NSString *str = [NSString stringWithFormat:@"合计金额 ¥%.2f&quo ...

  8. Redis的KEYS命令引起宕机事件

    摘要: 使用 Redis 的开发者必看,吸取教训啊! 原文:Redis 的 KEYS 命令引起 RDS 数据库雪崩,RDS 发生两次宕机,造成几百万的资金损失 作者:陈浩翔 Fundebug经授权转载 ...

  9. [转] tomcat 7/8 启动非常慢的解决方法

    在日志中发现启动慢的地方: -- ::] INFO o.s.c.s.DefaultLifecycleProcessor - Starting beans -- ::] INFO o.s.web.con ...

  10. error connecting: Timeout expired 超时时间已到. 达到了最大池大小 错误及Max Pool Size设置

    [参考]Timeout expired 超时时间已到. 达到了最大池大小 错误及Max Pool Size设置 [参考][数据库-MySql] MySqlConnection error connec ...