`

Java多线程之 concurrent 并发包

阅读更多
  
Java Tutorials -> Concurrency:
http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html
Java Concurrency Utilities:
http://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/index.html


作者 Doug Lea 的个人主页,里头不少好东西:
http://g.oswego.edu/



http://www.vogella.com/articles/JavaConcurrency/article.html
http://tutorials.jenkov.com/java-util-concurrent/index.html

concurrent 包详解:
http://www.cnblogs.com/crazybit/p/3150806.html


线程同步: 待完善。。。
concurrent 包之前,我们可以使用 synchronized 关键字实现线程同步;cooncurrent 包之后,实现 synchronization 的方式除了 synchronized keyword 之外,你还可以使用:
CountDownLatch: A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
CyclicBarrier: A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.
Semaphore



如果通过ExecutorService创建了n个线程,那在主线程中是怎么知道ExecutorService中所有的Callable是否都已经执行完毕那?答案是Callable接口的返回值!Callable接口是有返回值的,该返回值封装在ExecutorService的返回值Future里。Future值返回的时候,也就是ExecutorService所起的线程执行完毕的时候;而主线程中,可以将所起线程的返回值Future赋给一个局部变量,从而实现“所起线程未执行完毕时主线程卡在局部变量的赋值操作上,所起线程执行完毕后主线程才继续往下走”的效果。
http://stackoverflow.com/questions/3269445/executorservice-how-to-wait-for-all-tasks-to-finish


使用ExecutorService,一定记得在用完后调用其executorService.shutdown()将其shutdown掉;如果你未调用shutdown()的话,则executorService所起的线程不会退出(这些线程在等着你往其中加入更多的tasks),而这会导致jvm无法退出。
shutdown()方法不会立即terminated掉executorService,只是使其不再接受新的tasks,已submmit入其中的tasks会继续执行,这些already submmitted tasks都执行完后,executorService才会真正的terminated。
如果想立即terminated掉executorService,使用executorService.shutdownNow(),该方法不光使executorService不再接受新的tasks,而且会使其尝试终止所有已提交(尚未开始或尚未完成)的tasks。
http://tutorials.jenkov.com/java-util-concurrent/executorservice.html
引用
Closing an ExecutorService
When you are done using the ExecutorService you should shut it down, so the threads do not keep running.
For instance, if your application is started via a main() method and your main thread exits your application, the application will keep running if you have an active ExexutorService in your application. The active threads inside this ExecutorService prevents the JVM from shutting down.
To terminate the threads inside the ExecutorService you call its shutdown() method. The ExecutorService will not shut down immediately, but it will no longer accept new tasks, and once all threads have finished current tasks, the ExecutorService shuts down. All tasks submitted to the ExecutorService before shutdown() is called, are executed.
If you want to shut down the ExecutorService immediately, you can call the shutdownNow() method. This will attempt to stop all executing tasks right away, and skips all submitted but non-processed tasks. There are no guarantees given about the executing tasks. Perhaps they stop, perhaps the execute until the end. It is a best effort attempt.




invokeAll 是 blocking 的,future.get 也是 blocking 的。那么,invokeAll 后,在 for 里的 future.get 会阻塞当前线程吗?
invokeAll(tasks),即调用不带超时的 invokeAll 后, future.get 肯定不会阻塞当前线程,因为 invokeAll(tasks) 阻塞结束后,所有的 tasks 的 Future.isDone 都已经是 true 了(Returns true if this task completed. Completion may be due to normal termination, an exception, or cancellation -- in all of these cases, this method will return true)。
invokeAll(tasks, timeout,unit),即调用带超时的 invokeAll 后,future.get 其实也不会阻塞当前线程,因为这是 tasks 或者是 completed,或者是 cancelled了,详见带超时invokeAll的注释。
代码例子:待补
引申
试想一种场景:实现类似 invokeAll 的批量提交 task,但又不希望其阻塞当前外围线程,怎么做? 待补且查。。。。
http://stackoverflow.com/questions/18493318/is-there-a-non-blocking-method-analogous-to-executorservice-invokeall
http://stackoverflow.com/questions/826212/java-executors-how-to-be-notified-without-blocking-when-a-task-completes



invokeAll vs CompletionService:待补



execute() 和 submit() :
这两个方法都是立即提交 task 给线程池中的线程,不会阻塞当前外围线程的执行。但它们还是有些区别的:
http://stackoverflow.com/questions/3929342/choose-between-executorservices-submit-and-executorservices-execute
主要有一下几点:
1. execute 只可以传 Runnable 作为参数,submit() 的参数既可以 Runnable,也可以是并发包里新增的 Callable。
2. submit 的返回值是包含了 result 的 Future,而 execute 的返回值为 void。
3. 当提交的任务在线程池中执行遇到异常时:
submit 会将抛出的异常绑定到其返回结果 Future 上,当你试图在外围线程中调用 Future.get() 时,会抛出以 Future 绑定的异常作为 cause 的 ExecutionException;
execute 则会导致运行 task 的线程的 UncaughtExceptionHandler 被执行。
引申:
当 使用 execute 提交 task 到 threadpool 中,如果发生异常,会使运行 task 的线程 terminated 掉吗? 待补。。。





关于 RejectedExecutionException:
http://stackoverflow.com/questions/8183205/what-could-cause-of-rejectedexecutionexception
http://examples.javacodegeeks.com/core-java/util/concurrent/rejectedexecutionexception/java-util-concurrent-rejectedexecutionexception-how-to-solve-rejectedexecutionexception/
抛出该异常可能有两种原因:
1. executor 已经 shuttdown 掉;
2. 线程池的 task queue 满了且所有 worker thread 都没闲着,而你恰好此时将往其中提交(使用execute(),或submit())新的task。
当 task 的执行比较耗时,且 task 又比较多致使其迅速将 task queue 占满时,第二种抛 RejectedExecutionException 的情况就极有可能发生。这时,我们就需要某种机制,来保证此种情况下线程池任然能够有条不紊正常的工作:
http://stackoverflow.com/questions/2001086/how-to-make-threadpoolexecutors-submit-method-block-if-it-is-saturated





Using Callable to Return Results From Runnables:
https://blogs.oracle.com/CoreJavaTechTips/entry/get_netbeans_6



ReentrantReadWriteLock:
Many readers may acquire the read lock at once, as long as the write lock is free; writer may acquire the write lock only if no other lock is acquired (either read or write).
http://java.dzone.com/news/java-concurrency-read-write-lo?page=0,0
分享到:
评论

相关推荐

    java多线程处理数据库数据

    本主题将深入探讨如何使用Java的并发包(java.util.concurrent)来实现多线程对数据库数据的批量处理,包括增、删、改等操作。 首先,我们需要了解Java中的线程基础。线程是程序执行的最小单位,一个进程可以包含多...

    jdk1.6API中文+concurrent并发包API介绍.zip

    包含了java1.6 API的中文工具,能对API进行查找,查看中文描述,对API类里面的结构,构造器,方法,成员变量都能一目了然,并且打包concurrent并发包,助你在java多线程道路上一帆风顺。

    Java多线程编程

    以上就是Java多线程编程的关键点,理解并熟练运用这些概念和工具,能够帮助开发者编写出高效、稳定的多线程应用程序。在实际工作中,应结合具体需求和场景,选择合适的方法来实现并发控制,提高程序性能。

    Java 模拟线程并发

    此外,Java 5引入了java.util.concurrent并发包,提供了更高级的线程管理工具,如ExecutorService、ThreadPoolExecutor和Future。ExecutorService允许我们创建线程池,有效地管理线程生命周期,避免频繁创建和销毁...

    java多线程设计

    本知识点将深入探讨Java多线程设计以及如何利用“不可变对象”(immutable objects)来避免多线程环境中的非安全问题。 一、Java多线程基础 1. 线程的创建:Java提供了两种创建线程的方式——继承Thread类和实现...

    Java多线程设计模式(带源码)

    本资源提供了详细的Java多线程设计模式的解析,包括源码分析,帮助开发者深入理解并熟练应用这些模式。 在多线程环境中,设计模式是解决常见问题的最佳实践,它们可以帮助开发者创建高效、可维护的并发代码。以下是...

    Java多线程编辑核心技术

    Java的并发包java.util.concurrent是Java多线程编程中的重要组成部分,它提供了比原生的java.lang.Thread类和synchronized关键字更高级的并发工具。比如,它提供了线程池的实现(如ExecutorService和...

    java多线程进阶

    4. **并发工具类**:Java并发包(`java.util.concurrent`)中的各种工具类,如`ExecutorService`, `Future`, `Callable`, `CountDownLatch`, `CyclicBarrier`, `Semaphore`等,都是提高并发效率的关键工具,书里会详细...

    JAVA多线程的实例

    总的来说,Java多线程涉及到线程创建、同步、通信、管理等多个方面,理解并熟练掌握这些知识点对于编写高效、稳定的并发程序至关重要。在实际开发中,我们需要根据具体需求选择合适的方法来处理多线程问题。

    深入学习:Java多线程编程

    理解并掌握Java多线程能够提升程序的效率、响应速度以及资源利用率。 本书可能涵盖了以下几个重要的知识点: 1. **线程基础**:首先,书中可能会介绍线程的基本概念,包括进程与线程的区别,以及Java中创建线程的...

    java多线程编程实例_Source

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,提升系统效率。在本实例源码中,包含17个章节和上百个实例,旨在深入讲解Java多线程的核心概念和实际应用。 一、线程基础知识 在Java中,...

    Java多线程实例图形版

    此外,我们还可以利用Java并发包(java.util.concurrent)中的其他工具类,如CyclicBarrier(回环栅栏)或CountDownLatch(倒计时 latch),来协调多个线程的同步行为,确保所有哲学家按照一定的顺序进行操作。...

    java 多线程编程指南

    总之,“Java多线程编程指南”将涵盖这些核心概念,并可能深入到高级话题,如线程池的优化、并发容器的使用以及并发编程的最佳实践,帮助读者提升在多线程环境下的编程能力。通过深入学习和实践,开发者能够构建出...

    Java多线程程序设计

    Java多线程程序设计是Java开发中的重要领域,它允许应用程序同时执行多个任务,从而提高系统资源的利用率和程序的响应速度。在Java中,多线程主要通过两种方式实现:继承Thread类和实现Runnable接口。 一、创建线程...

    java多线程_java多线程下变量共享_

    Java多线程是Java编程中的重要概念,它允许...理解并掌握Java多线程下变量共享的原理和解决方案,有助于编写出高效、稳定的并发程序。在实际开发中,应结合具体业务场景选择合适的同步机制,以达到最佳性能和安全性。

    java5 并发包 (concurrent)思维导图

    Java 5并发包(`java.util.concurrent`,简称`Concurrent`包)是Java平台中用于多线程编程的重要组成部分,它提供了丰富的并发工具类,极大地简化了在多线程环境下的编程工作。这个包的设计目标是提高并发性能,减少...

    java多线程测试实例

    Java多线程是Java编程中的重要组成部分,尤其在并发编程领域,它扮演着...这个"java多线程测试实例"可能包含了上述部分或全部知识点的实际应用,通过下载并分析实例代码,可以加深对Java多线程编程的理解和实践能力。

    多线程并行执行,汇总结果

    `CountDownLatch`是Java并发包(java.util.concurrent)中的一个计数器类,它允许一个或多个线程等待其他线程完成操作。在初始化时,`CountDownLatch`需要一个非负整数作为计数器的初始值。每次调用`countDown()`...

    java多线程编程大总结

    然而,从Java 5开始,Java引入了并发包(java.util.concurrent),这个扩展大大提升了Java多线程编程的能力,使开发者能够更方便地编写复杂的多线程程序。并发包中提供了很多高级功能,比如线程池、同步工具、并发...

    java多线程(生产者与消费者)

    Java多线程是一种编程模型,它允许程序同时执行多个任务,从而提高系统效率。在Java中,实现多线程可以通过继承Thread类或者实现Runnable接口来完成。在这个“生产者与消费者”模式中,我们主要关注如何安全地共享...

Global site tag (gtag.js) - Google Analytics