- 浏览: 874830 次
- 性别:
- 来自: 北京
博客专栏
-
Java Concurre...
浏览量:97538
文章分类
最新评论
-
guo_guo_guo:
mark
Zookeeper 安装和配置 -
solrer:
xunux 写道windows下,dataDir目录若是用需要 ...
Zookeeper 安装和配置 -
kevlearnjava:
你好 我是按照你的伪集群进行配置的 然后启动第二个和第三个 ...
Zookeeper 安装和配置 -
筑浪小子:
博主应该把vector设定为全局变量,更加清晰一些
线程安全的集合类--Java Concurrency In Practice C05读书笔记 -
tt5753:
jps16437 QuorumPeerMain16663 Zo ...
Zookeeper 安装和配置
[coolxing按: 转载请注明作者和出处, 如有谬误, 欢迎在评论中指正.]
服务器应用程序经常需要处理执行时间很短而数目巨大的请求, 如果为每一个请求创建一个新的线程, 会导致一些问题的出现, 如:
1. 性能瓶颈. 线程的创建和销毁需要执行大量的后台操作, 如果单个请求的执行时间很短, 有可能花在创建和销毁线程上的时间大于真正执行请求的时间.
2. 可能会导致资源不足. 大量的并发请求意味着需要创建大量的线程, 过多的线程存在会吞噬大量的系统资源, 而且CPU需要在这些线程间不断切换, 这可能引发"切换过度"的问题.
为了适应上述场合, java在JDK1.5中引入了线程池的概念. 线程池中存放着一定数量的已创建好的线程, 当一个请求到来时, 只需从线程池中取出一个线程来执行请求, 请求完成后再将线程归还给线程池. 同时, 我们可以为线程池指定最大的线程数量, 当池中所有线程都处于活动状态下, 新的任务会排队等候, 直到之前的某个任务处理完成后, 新的任务才能得到处理.
创建线程池. java.util.concurrent.Executors类提供了多个静态方法用于创建线程池.
|--public static ExecutorService newFixedThreadPool(int nThreads): 创建一个可重用的固定线程数的线程池. 如果池中所有的nThreads个线程都处于活动状态时提交任务(任务通常是Runnable或Callable对象), 任务将在队列中等待, 直到池中出现可用线程.
|--public static ExecutorService newCachedThreadPool(): 调用此方法创建的线程池可根据需要自动调整池中线程的数量. 执行任务时将重用存在先前创建的线程(如果池中存在可用线程的话). 如果池中没有可用线程, 将创建一个新的线程, 并将其添加到池中. 池中的线程超过60秒未被使用就会被销毁, 因此长时间保持空闲的CachedThreadPool不会消耗额外的资源.
|--public static ExecutorService newSingleThreadExecutor(): 创建一个单线程的Executor. 这个Executor保证按照任务提交的顺序依次执行任务.
|--public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize): 创建一个可重用的固定线程数的线程池. ScheduledExecutorService是ExecutorService的子接口, 调用ScheduledExecutorService的相关方法, 可以延迟或定期执行任务.
以上静态方法均使用默认的ThreadFactory(即
Executors.defaultThreadFactory()方法的返回值)创建线程, 如果想要指定ThreadFactory, 可调用他们的重载方法.通过指定ThreadFactory, 可以定制新建线程的名称, 线程组, 优先级, 守护线程状态等.
如果Executors提供的创建线程池的方法无法满足要求, 可以使用ThreadPoolExecutor类创建线程池.
提交任务. 所有的线程池都是ExecutorService及其子类的对象, 因此, 可以调用ExecutorService的相关方法提交任务.
|--void execute(Runnable command): 使用池中已存在的线程或新建一个线程执行command.
public class ExecutorsDemo { public static void main(String[] args) throws Exception { System.out.println("----------------FixedThreadPool---------------------"); ExecutorService fixedPool = getFixedThreadPool(); executeThread(fixedPool); // 为了避免混淆, 需要等待executeThread(fixedPool)执行完成 Thread.sleep(3000); System.out.println("----------------CashedThreadPool---------------------"); ExecutorService cashedPool = getCashedThreadPool(); executeThread(cashedPool); // 为了避免混淆, 需要等待executeThread(cashedPool)执行完成 Thread.sleep(3000); System.out.println("----------------SingleThreadExecutor---------------------"); ExecutorService singleExecutor = getSingleThreadExecutor(); executeThread(singleExecutor); } // 只存在一个线程的线程池 private static ExecutorService getSingleThreadExecutor() { return Executors.newSingleThreadExecutor(); } // 创建一个根据需要自动调整大小的线程池 private static ExecutorService getCashedThreadPool() { return Executors.newCachedThreadPool(); } // 创建一个可重用的固定线程数的线程池 private static ExecutorService getFixedThreadPool() { return Executors.newFixedThreadPool(2); } private static void executeThread(ExecutorService pool) { Thread t1 = new MyThread(); Thread t2 = new MyThread(); Thread t3 = new MyThread(); Thread t4 = new MyThread(); // 将Tread放入线程池中执行 // MyThread类继承自Thread, 而Thread类实现了Runnable接口 pool.execute(t1); pool.execute(t2); pool.execute(t3); pool.execute(t4); // 关闭线程池 pool.shutdown(); } private static final class MyThread extends Thread { @Override public void run() { super.run(); System.out.println(Thread.currentThread().getName() + ": is running!"); } } }
程序的输出为:
----------------FixedThreadPool---------------------
pool-1-thread-1: is running!
pool-1-thread-2: is running!
pool-1-thread-2: is running!
pool-1-thread-1: is running!
----------------CashedThreadPool---------------------
pool-2-thread-1: is running!
pool-2-thread-2: is running!
pool-2-thread-4: is running!
pool-2-thread-3: is running!
----------------SingleThreadExecutor---------------------
pool-3-thread-1: is running!
pool-3-thread-1: is running!
pool-3-thread-1: is running!
pool-3-thread-1: is running!
|--Future<T> submit(Callable<T> task): 使用池中已存在的线程或新建一个线程执行task, 与execute()方法不同的是, 该方法会返回线程的执行结果. submit方法接受一个Callable<T>对象, Callable<T>接口是一个泛型接口, 实现Callable<T>接口需要重写其中的call()方法, call()方法将返回一个T对象. submit方法的返回值是Future<T>对象, 调用该对象的get()可以获得call()方法的返回值.
public class FutureDemo { public static void main(String[] args) throws Exception { ExecutorService pool = Executors.newFixedThreadPool(2); Future<Integer> intFuture = pool.submit(new IntegerCallable()); // get()方法将阻塞主线程, 直到IntegerCallable线程的call()运行结束并返回结果时为止. Integer returnInt = intFuture.get(); System.out.println("返回值为" + returnInt); Future<Boolean> boolFuture = pool.submit(new BooleanCallable()); Boolean returnBool = boolFuture.get(); System.out.println("返回值为" + returnBool); pool.shutdown(); } private final static class IntegerCallable implements Callable<Integer> { // call()方法的返回值类型由泛型决定 @Override public Integer call() throws Exception { return 2; } } private final static class BooleanCallable implements Callable<Boolean> { @Override public Boolean call() throws Exception { return true; } } }
程序的输出结果为:
返回值为2
返回值为true
|--List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks): 批量执行多个任务.
Future类. 如果需要获取线程的执行结果, 那么就会使用到Future. Future对象是一个指向异步执行结果的引用, 由于线程的异步特性, Future对象在其创建之初可能并不可用, 比如线程的call()方法尚未完成时. 可以调用Future对象的isDone()方法判断线程结果是否已经可用, 在线程结果返回之前调用Future对象的get()方法, 将导致阻塞.
关闭线程池. 使用完线程池后需要关闭它, 否则程序可能一直处于运行状态. ExecutorService提供了2个方法用于关闭线程池:
|--void shutdown(): 关闭线程池, 不再接受新任务. 如果存在正在执行的任务, 则等待任务执行完成.
|--List<Runnable> shutdownNow(): 关闭线程池, 不再接受新任务. 尽力尝试停止正在执行的任务, 并返回正在等待的任务列表.
|--boolean isShutdown(): 判断线程池是否已经关闭.
发表评论
-
状态依赖的类--JCIP C14.1读书笔记
2012-04-11 10:24 2665[本文是我对Java Concurrency In Pract ... -
内置锁和显式锁的区别--JCIP C13读书笔记
2012-04-11 10:17 5782[本文是我对Java Concurrenc ... -
改善并发程序的可扩展性--JCIP C11读书笔记
2012-04-10 14:40 2512[本文是我对Java Concurrency In Pract ... -
如何避免死锁--JCIPC10读书笔记
2012-04-10 10:08 3156[本文是我对Java Concurrency In Pract ... -
task与execution--JCIPC08读书笔记
2012-04-09 10:34 2402[本文是我对Java Concurrency In Pract ... -
配置ThreadPoolExecutor
2012-04-09 10:34 6234[本文是我对Java Concurrency In Pract ... -
停止基于线程的Service--JCIP7.2读书笔记
2012-04-06 10:28 2336[本文是我对Java Concurrency In Pract ... -
处理不可中断的阻塞-JCIP7.1读书笔记
2012-04-06 10:23 5703[本文是我对Java Concurrenc ... -
处理InterruptedException异常--JCIP7.1读书笔记
2012-04-05 14:08 6128[本文是我对Java Concurrency In Pract ... -
中断线程--JCIP7.1读书笔记
2012-04-05 14:03 2615[本文是我对Java Concurrency In Pract ... -
改善并发性能--JCIP6.3读书笔记
2012-04-02 11:51 2573[本文是我对Java Concurrency In Pr ... -
Executor--JCIP C06读书笔记
2012-04-02 09:28 2864[本文是我对Java Concurrency In Pract ... -
设计高效的线程安全的缓存--JCIP5.6读书笔记
2012-04-01 22:49 5872[本文是我对Java Concurrency In Pract ... -
synchronizer--JCIP5.5读书笔记
2012-04-01 22:44 2348[本文是我对Java Concurrency In Pract ... -
使用BlockingQueue构建生产者消费者模式--JCIP5.3读书笔记
2012-03-31 17:32 4644[本文是我对Java Concurrency In Pract ... -
ConcurrentHashMap和CopyOnWriteArrayList--Java Concurrency In Practice C05读书笔记
2012-03-31 11:27 4043[本文是我对Java Concurrenc ... -
线程安全的集合类--Java Concurrency In Practice C05读书笔记
2012-03-28 18:26 14250[本文是我对Java Concurrency In Pract ... -
利用对象限制和委托构建线程安全的类--Java Concurrency In Practice C04读书笔记
2012-03-27 18:23 3830[本文是我对Java Concurrency In Pract ... -
变量可见性和volatile, this逃逸, 不可变对象, 以及安全公开--Java Concurrency In Practice C03读书笔记
2012-03-26 21:55 12585[本文是我对Java Concurrency In Pract ... -
变量可见性和volatile, this逃逸, 不可变对象, 以及安全公开--Java Concurrency In Practice C02读书笔记
2012-03-26 21:53 2[本文是我对Java Concurrency In Pract ...
相关推荐
阿里专家级并发编程架构师级课程,完成课程的学习可以帮助同学们解决非常多的JAVA并发编程疑难杂症,极大的提高JAVA并发编程的效率。课程内容包括了JAVA手写线程池,UC线程池API详解,线程安全根因详解,锁与原子类...
深入理解高并发编程-Java线程池核心技术 全面详解Java线程池核心技术
Java并发编程实践中的线程池是一个关键的概念,它在多线程编程中扮演着至关重要的角色,有效地管理和调度线程资源,以提高系统的性能和效率。线程池通过复用已存在的线程来减少线程的创建和销毁开销,避免了频繁的上...
最后,线程池(ThreadPoolExecutor)是Java并发编程中不可或缺的一部分。通过合理配置线程池,我们可以有效地管理和调度线程,避免资源过度消耗,提高系统性能。 总之,“java并发编程-从入门到精通”这个文档会...
总结来说,理解Java并发编程中的线程和线程池技术,包括它们的实现方式、生命周期、执行顺序控制、异步计算模型以及线程安全问题,是提高程序性能和可扩展性的关键。通过合理使用线程池,我们可以有效地管理线程,...
在Java编程中,线程池是一种高效管理线程资源的方式,可以提高系统的性能和响应速度。本篇将探讨如何模拟Java的JDK线程池执行流程,以理解其设计原理。核心知识点包括线程池的执行策略、接口设计以及异常处理。 ...
根据提供的信息,“Java 并发编程实战.pdf”这本书聚焦于Java并发编程的实践与应用,旨在帮助读者深入了解并掌握Java中的多线程技术及其在实际项目中的应用技巧。虽然部分内容未能提供具体章节或实例,但从标题及...
通过以上实践,我们可以更好地理解如何在Socket网络编程中利用线程池优化性能,这对于开发高并发的网络服务具有重要的指导意义。在实际项目中,结合具体的业务需求调整线程池参数,可以进一步提升系统的稳定性和效率...
总结,Java并发编程涵盖了大量的概念和技术,包括线程的创建、同步、通信以及并发工具的使用。理解和掌握这些知识点,是成为一名合格的Java并发程序员的基础。在实际开发中,应结合具体场景选择合适的并发策略,以...
"java并发编程-构建块"这个主题涵盖了使程序能够同时处理多个任务的关键概念和技术。在这个主题下,我们将深入探讨Java中用于构建高效并发应用的核心工具和概念。 1. **线程**:Java中的线程是并发编程的基础,每个...
《Java并发编程实战》是Java并发编程领域的一本经典著作,它深入浅出地介绍了如何在Java平台上进行高效的多线程编程。这本书的源码提供了丰富的示例,可以帮助读者更好地理解书中的理论知识并将其应用到实际项目中。...
Java并发编程是Java开发中的重要领域,特别是在多核处理器和分布式系统中,高效地利用并发可以极大地提升程序的性能和响应速度。以下是对标题和描述中所提及的几个知识点的详细解释: 1. **线程与并发** - **线程*...
本文将深入探讨"Java并发编程-线程安全与基础构建模块"这一主题,旨在帮助开发者理解如何有效地处理并发问题,提高程序性能和稳定性。 首先,线程安全是并发编程中的核心概念,指的是多个线程访问同一资源时,无论...
《Java并发编程实战》是一本深入探讨Java平台并发编程的权威指南。这本书旨在帮助开发者理解和掌握在Java环境中创建高效、可扩展且可靠的多线程应用程序的关键技术和实践。它涵盖了从基本概念到高级主题的广泛内容,...
《JAVA并发编程实践》是Java开发人员深入理解并发编程的一本经典著作,由Doug Lea撰写,本书中文版高清完整,包含丰富的书签,便于读者查阅和学习。这本书旨在帮助开发者掌握在Java平台上进行高效、安全并发编程的...
总的来说,这份“java并发编程内部分享PPT”涵盖了Java并发编程的多个重要方面,包括线程创建与管理、同步机制、并发容器、线程池、并发问题以及异步计算。通过深入学习和实践这些知识点,开发者可以更好地应对多...
《Java并发编程实战》是一本深入探讨Java平台并发编程的权威指南,由Tim Peierls等人与Brian Goetz合著,旨在帮助Java开发者理解和掌握在多线程环境中编写高效、安全的代码。这本书由拥有丰富经验的JDK并发大师及...
《JAVA并发编程艺术》是Java开发者深入理解和掌握并发编程的一本重要著作,它涵盖了Java并发领域的核心概念和技术。这本书详细阐述了如何在多线程环境下有效地编写高效、可靠的代码,对于提升Java程序员的技能水平...