- 浏览: 498172 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
herofighter2008:
图呢?图呢?图呢?图呢?
BlockingQueue -
zy13608089849:
请问一下博主,文中几处提到的图,怎么都没有?是我这显示不出来还 ...
BlockingQueue -
swift911:
在短信的场景下很好用,感谢分享
BlockingQueue -
tony_0529:
学习了~谢谢分享。
BlockingQueue -
Master-Gao:
...
BlockingQueue
前记: 查看JDK帮助文档,可以发现该类比较简单,继承自AbstractExecutorService,而AbstractExecutorService实现了ExecutorService接口。 ThreadPoolExecutor的完整构造方法的签名是: 先记着,后面慢慢解释。 ===============================神奇分割线================================== 其实对于ThreadPoolExecutor的构造函数网上有N多的解释的,大多讲得都很好,不过我想先换个方式,从Executors这个类入手。因为他的几个构造工厂构造方法名字取得令人很容易了解有什么特点。但是其实Executors类的底层实现便是ThreadPoolExecutor! ThreadPoolExecutor是Executors类的底层实现。 在JDK帮助文档中,有如此一段话: “强烈建议程序员使用较为方便的 ===============================神奇分割线================================== OK,那就来看看源码吧,从newFixedThreadPool开始。 ExecutorService newFixedThreadPool(int nThreads):固定大小线程池。 可以看到,corePoolSize和maximumPoolSize的大小是一样的(实际上,后面会介绍,如果使用无界queue的话maximumPoolSize参数是没有意义的),keepAliveTime和unit的设值表名什么?-就是该实现不想keep alive!最后的BlockingQueue选择了LinkedBlockingQueue,该queue有一个特点,他是无界的。 ExecutorService newSingleThreadExecutor():单线程。 可以看到,与fixedThreadPool很像,只不过fixedThreadPool中的入参直接退化为1 ExecutorService newCachedThreadPool():无界线程池,可以进行自动线程回收。 这个实现就有意思了。首先是无界的线程池,所以我们可以发现maximumPoolSize为big big。其次BlockingQueue的选择上使用SynchronousQueue。可能对于该BlockingQueue有些陌生,简单说:该QUEUE中,每个插入操作必须等待另一个 线程的对应移除操作。比如,我先添加一个元素,接下来如果继续想尝试添加则会阻塞,直到另一个线程取走一个元素,反之亦然。(想到什么?就是缓冲区为1的生产者消费者模式^_^) 注意到介绍中的自动回收线程的特性吗,为什么呢?先不说,但注意到该实现中corePoolSize和maximumPoolSize的大小不同。 ===============================神奇分割线================================== 到此如果有很多疑问,那是必然了(除非你也很了解了) 先从BlockingQueue<Runnable> workQueue这个入参开始说起。在JDK中,其实已经说得很清楚了,一共有三种类型的queue。以下为引用:(我会稍微修改一下,并用红色突出显示) ===============================神奇分割线================================== 到这里,该了解的理论已经够多了,可以调节的就是corePoolSize和maximumPoolSizes 这对参数还有就是BlockingQueue的选择。 例子一:使用直接提交策略,也即SynchronousQueue。 首先SynchronousQueue是无界的,也就是说他存数任务的能力是没有限制的,但是由于该Queue本身的特性,在某次添加元素后必须等待其他线程取走后才能继续添加。在这里不是核心线程便是新创建的线程,但是我们试想一样下,下面的场景。 我们使用一下参数构造ThreadPoolExecutor: 当核心线程已经有2个正在运行. OK,此时任务变加入队列之中了,那什么时候才会添加新线程呢? 这里就很有意思了,可能会出现无法加入队列吗?不像SynchronousQueue那样有其自身的特点,对于无界队列来说,总是可以加入的(资源耗尽,当然另当别论)。换句说,永远也不会触发产生新的线程!corePoolSize大小的线程数会一直运行,忙完当前的,就从队列中拿任务开始运行。所以要防止任务疯长,比如任务运行的实行比较长,而添加任务的速度远远超过处理任务的时间,而且还不断增加,如果任务内存大一些,不一会儿就爆了,呵呵。 可以仔细想想哈。 例子三:有界队列,使用 这个是最为复杂的使用,所以JDK不推荐使用也有些道理。与上面的相比,最大的特点便是可以防止资源耗尽的情况发生。 举例来说,请看如下构造方法: 假设,所有的任务都永远无法执行完。 对于首先来的A,B来说直接运行,接下来,如果来了C,D,他们会被放到queu中,如果接下来再来E,F,则增加线程运行E,F。但是如果再来任务,队列无法再接受了,线程数也到达最大的限制了,所以就会使用拒绝策略来处理。 总结:
一、ThreadPoolExecutor使用和思考(上)-线程池大小设置与BlockingQueue的三种实现区别
LinkedBlockingQueue,
ArrayBlockingQueue
);中篇中主要聊聊与keepAliveTime这个参数相关的话题;下片中介绍一下一些比较少用的该类的API,及他的近亲:ScheduledThreadPoolExecutor。
ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler)
Executors
工厂方法 Executors.newCachedThreadPool()
(无界线程池,可以进行自动线程回收)、Executors.newFixedThreadPool(int)
(固定大小线程池)和Executors.newSingleThreadExecutor()
(单个后台线程),它们均为大多数使用场景预定义了设置。”可以推断出ThreadPoolExecutor与Executors类必然关系密切。
BlockingQueue
都可用于传输和保持提交的任务。可以使用此队列与池大小进行交互:
SynchronousQueue
,它将任务直接提交给线程而不保持它们。在此,如果不存在可用于立即运行任务的线程,则试图把任务加入队列将失败,因此会构造一个新的线程。此策略可以避免在处理可能具有内部依赖性的请求集时出现锁。直接提交通常要求无界 maximumPoolSizes 以避免拒绝新提交的任务。当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性。LinkedBlockingQueue
)将导致在所有 corePoolSize 线程都忙时新任务在队列中等待。这样,创建的线程就不会超过 corePoolSize。(因此,maximumPoolSize 的值也就无效了。)当每个任务完全独立于其他任务,即任务执行互不影响时,适合于使用无界队列;例如,在 Web 页服务器中。这种排队可用于处理瞬态突发请求,当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性。ArrayBlockingQueue
)有助于防止资源耗尽,但是可能较难调整和控制。队列大小和最大池大小可能需要相互折衷:使用大型队列和小型池可以最大限度地降低 CPU 使用率、操作系统资源和上下文切换开销,但是可能导致人工降低吞吐量。如果任务频繁阻塞(例如,如果它们是 I/O 边界),则系统可能为超过您许可的更多线程安排时间。使用小型队列通常要求较大的池大小,CPU 使用率较高,但是可能遇到不可接受的调度开销,这样也会降低吞吐量。
LinkedBlockingQueue
ArrayBlockingQueue。
RejectedExecutionException
发表评论
-
HashMap的非线程安全
2013-11-25 16:06 925在平时开发中,我们经常采用HashMap来作为本地缓存的一种 ... -
SynchronousQueue
2012-08-11 23:30 13328SynchronousQueue是这样一种阻塞队列,其中每个 ... -
Java Atomic
2012-05-09 21:13 4252我们知道volatile修饰的变量可以实现基本的加载和赋值的原 ... -
ArrayList线程不安全分析
2012-04-22 17:49 8646一个 ArrayList ,在添加一个元素的时候,它可能会有两 ... -
ConcurrentModificationException
2012-04-22 16:38 1344如果在获得了某个集合的迭代器之后,除了通过这个迭代器之外对该集 ... -
LinkedBlockingQueue和ConcurrentLinkedQueue
2012-04-21 14:19 80481.LinkedBlockingQueue<E>: ... -
(转)深入研究ReentrantLock(重入锁)之引出话题篇
2012-04-20 20:28 1209一直以来都想好好研究下ReentrantLock,她的独到魅力 ... -
ReentrantLock和synchronized的区别随笔
2012-04-20 20:27 2483可重入锁 ReentrantLock 的含义是: ... -
(转)ReentrantLock和synchronized两种锁定机制的对比
2012-04-20 20:07 1045多线程和并发性并不是什么新内容,但是 Java 语言设计中的创 ... -
volatile变量
2012-02-20 21:26 1837我们知道,在Java中设置变量值的操作,除了long和doub ... -
(转)java并发编程-Executor框架
2012-01-17 09:42 1048Executor框架是指java 5中引入的一系列并发库中 ... -
ThreadLocal的几种误区
2011-11-05 22:54 954最近由于需要用到ThreadLocal,在网上搜索 ... -
正确理解ThreadLocal
2011-11-05 22:41 1329首先, ThreadLocal 不是用来解决 ...
相关推荐
(转)线程池:java_util_ThreadPoolExecutor 比较详细的介绍了ThreadPoolExecutor用法与属性
根据提供的文件信息,我们可以深入探讨线程池`ThreadPoolExecutor`的工作原理及其实现细节,同时也会涉及并发编程中的一些关键概念和技术。 ### 线程池`ThreadPoolExecutor`概述 `ThreadPoolExecutor`是Java中非常...
根据给定文件的信息,我们可以深入探讨Java中`ThreadPoolExecutor`线程池的底层实现原理,特别是其核心数据结构`ctl`以及线程池的各种状态转换。以下是对这些知识点的详细解释: ### 一、线程池`ThreadPoolExecutor...
这个类是Spring对Java内置的`java.util.concurrent.ThreadPoolExecutor`的封装,允许开发者在Spring应用上下文中声明式地定义线程池。在本篇文章中,我们将深入探讨`ThreadPoolTaskExecutor`的配置及其使用,并结合`...
综上所述,"android 系统应用程序 网络数据转串口tcpToUart"项目涵盖了Android应用开发、网络通信、串口操作、多线程编程等多个方面,需要开发者具备扎实的技术基础和实践经验。项目中的"tcp2uart"和"eloop"可能是...
标题"13 转钱和查询余额 poolthread"表明我们关注的是使用线程池来实现金融应用中的转账和查询余额功能。这两个操作都需要高效、安全且并发友好的执行环境,线程池恰好能提供这样的支持。 线程池的概念源自多线程...
with ThreadPoolExecutor(max_workers=5) as executor: for url in ts_urls: executor.submit(download_ts, url, 'segment_%d.ts' % index) ``` 下载完成后,我们需要将所有.ts文件合并为一个MP4文件。这可以通过...
此外,还会讲解线程池的概念,如ExecutorService和ThreadPoolExecutor,这些都是Java并发编程中不可或缺的知识。 【第2章 初始MySQL】MySQL是一种广泛使用的开源关系型数据库管理系统(RDBMS)。本章将引导学员熟悉...
3. **线程池**:了解`ExecutorService`和`ThreadPoolExecutor`,以及如何根据需求配置和管理线程池,以优化资源使用。 4. **Future和Callable接口**:学习如何使用它们来管理和获取异步任务的结果。 5. **锁机制**...
在这个例子中,`ThreadPoolExecutor`创建了一个线程池,`map()`函数将`square`函数并行地应用到`lst`的每个元素上。 总结来说,Python的`map()`函数是处理可迭代对象的强大工具,能够帮助我们高效地对数据进行处理...
例如,`newFixedThreadPool`方法创建`ThreadPoolExecutor`实例时,传入了核心线程数、线程工厂和拒绝策略等参数,确保线程池的行为符合预期。 理解`Executors`类的源码对于优化线程池配置、避免资源泄露以及提高...
Java并发工具包中的ExecutorService接口和ThreadPoolExecutor类是线程池的核心。线程池允许开发者管理一组可重用的工作线程,以处理多个任务。通过线程池,可以有效地控制并发程度,减少线程创建和销毁的开销,提高...
3. 线程池:ExecutorService,ThreadPoolExecutor,Future接口。 七、网络编程 1. Socket编程:客户端和服务端的建立连接,数据传输。 2. URL和URLConnection:用于访问网络资源。 八、反射机制 1. Class类:获取...
1. ThreadPoolExecutor:ThreadPoolExecutor是一个线程池,通过Executors工厂类的方法可以构造出适用于不同应用场景下的ThreadPoolExecutor。 2. invokedynamic指令:invokedynamic指令是Java 7开始引入的字节码...
Java的`ExecutorService`和`ThreadPoolExecutor`类提供了线程池管理的功能,可以有效地管理和复用线程,减少系统资源的消耗。通过设置线程池的核心线程数、最大线程数、线程存活时间和工作队列,可以优化线程的创建...
2. **ExecutorService与ThreadPoolExecutor**:Java并发框架中的`ExecutorService`是线程池的接口,它提供了一种管理和控制线程的方法。`ThreadPoolExecutor`是其实现,通过设置核心线程数、最大线程数、线程存活...
在并发编程方面,Java提供了强大的工具,如线程池(ThreadPoolExecutor)、异步任务(CompletableFuture)等,这些都能有效管理多个并发任务,确保系统资源的高效利用。 REST(Representational State Transfer)...
Java平台提供了丰富的多线程工具,如ExecutorService和ThreadPoolExecutor,可以创建并管理线程池,有效地分配任务。通过多线程,系统可以并发处理多个视频文件,缩短整体处理时间,同时避免单个线程占用过多资源...
Android提供了多种异步解决方案,例如AsyncTask、Handler/Looper、IntentService、ThreadPoolExecutor等。其中,AsyncTask是最常用的一种方式,它为轻量级的异步操作提供了简洁的API,可以在后台线程执行任务并在...