
Java并发编程的艺术
文章平均质量分 82
凌澜星空
这个作者很懒,什么都没留下…
展开
-
Java并发容器大合集
概述 java.util包中的大部分容器都是非线程安全的,若要在多线程中使用容器,你可以使用Collections提供的包装函数:synchronizedXXX,将普通容器变成线程安全的容器。但该方法仅仅是简单地给容器使用同步,效率很低。因此并发大师Doug Lea提供了java.util.concurrent包,提供高效的并发容器。并且为了保持与普通的容器的接口一致性,仍然使用ut原创 2017-02-06 10:24:13 · 8154 阅读 · 6 评论 -
Java并发编程的艺术(一)——并发编程需要注意的问题
并发是为了提升程序的执行速度,但并不是多线程一定比单线程高效,而且并发编程容易出错。若要实现正确且高效的并发,就要在开发过程中时刻注意以下三个问题:上下文切换死锁资源限制接下来会逐一分析这三个问题,并给出相应的解决方案。问题一:上下文切换会带来额外的开销线程的运行机制一个CPU每个时刻只能执行一条线程;操作系统给每条线程分配不同长度的时间片;操作系统会从一堆线程中随机选取一条来执行;原创 2017-01-08 12:48:04 · 16513 阅读 · 1 评论 -
Java并发编程的艺术(二)——重排序
当我们写一个单线程程序时,总以为计算机会一行行地运行代码,然而事实并非如此。什么是重排序?重排序指的是编译器、处理器在不改变程序执行结果的前提下,重新排列指令的执行顺序,以达到最佳的运行效率。重排序分类重排序分为:编译器重排序 和 处理器重排序。数据依赖编译器和处理器并不会随意的改变指令的执行顺序,因为有些指令之间是有依赖关系的,若改变了他们的执行顺序,就会出现错误的结果。 因此,编译器和处理器只原创 2017-01-09 08:10:36 · 6374 阅读 · 1 评论 -
Java并发编程的艺术(三)——volatile
1. 并发编程的两个关键问题并发是让多个线程同时执行,若线程之间是独立的,那并发实现起来很简单,各自执行各自的就行;但往往多条线程之间需要共享数据,此时在并发编程过程中就不可避免要考虑两个问题:通信 与 同步。通信 通信是指消息在两条线程之间传递。 既然要传递消息,那接收线程 和 发送线程之间必须要有个先后关系,此时就需要用到同步。通信和同步是相辅相成的。同步 同步是指,控制多条线程之间的原创 2017-01-09 16:54:12 · 8064 阅读 · 6 评论 -
Java并发编程的艺术(四)——线程的状态
线程的状态初始态:NEW创建一个Thread对象,但还未调用start()启动线程时,线程处于初始态。运行态:RUNNABLE在Java中,运行态包括就绪态 和 运行态。就绪态 该状态下的线程已经获得执行所需的所有资源,只要CPU分配执行权就能运行。所有就绪态的线程存放在就绪队列中。运行态 获得CPU执行权,正在执行的线程。由于一个CPU同一时刻只能执行一条线程,因此每个CPU每个时刻只原创 2017-01-09 20:18:42 · 5418 阅读 · 0 评论 -
Java并发编程的艺术(五)——中断
什么是中断?在Java中没有办法立即停止一条线程,然而停止线程却显得尤为重要,如取消一个耗时操作。因此,Java提供了一种用于停止线程的机制——中断。中断只是一种协作机制,Java没有给中断增加任何语法,中断的过程完全需要程序员自己实现。若要中断一个线程,你需要手动调用该线程的interrupted方法,该方法也仅仅是将线程对象的中断标识设成true;接着你需要自己写代码不断地检测当前线程的标识位原创 2017-01-10 14:34:01 · 4492 阅读 · 0 评论 -
Java并发编程的艺术(六)——线程间的通信
多条线程之间有时需要数据交互,下面介绍五种线程间数据交互的方式,他们的使用场景各有不同。1. volatile、synchronized关键字PS:关于volatile的详细介绍请移步至:Java并发编程的艺术(三)——volatile1.1 如何实现通信?这两种方式都采用了同步机制实现多条线程间的数据通信。与其说是“通信”,倒不如说是“共享变量”来的恰当。当一个共享变量被volatile修饰 或原创 2017-01-11 10:43:08 · 6974 阅读 · 2 评论 -
Java并发编程的艺术(八)——闭锁、同步屏障、信号量详解
1. 闭锁:CountDownLatch1.1 使用场景若有多条线程,其中一条线程需要等到其他所有线程准备完所需的资源后才能运行,这样的情况可以使用闭锁。1.2 代码实现// 初始化闭锁,并设置资源个数CountDownLatch latch = new CountDownLatch(2);Thread t1 = new Thread( new Runnable(){ public voi原创 2017-01-17 09:23:40 · 5755 阅读 · 3 评论 -
Java并发编程的艺术(七)——Executors
Executors框架简介Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java.util.cocurrent 包下,通过该框架来控制线程的启动、执行和关闭,可以简化并发编程的操作。因此,在Java 5之后,通过Executor来启动线程比使用Thread的start方法更好,除了更易管理,效率更好(用线程池实现,节约开销)外,还有关键的一点:有助于避免this逸出。Ex原创 2017-01-17 09:33:15 · 3985 阅读 · 1 评论 -
Java并发编程的艺术(九)——批量获取多条线程的执行结果
当向线程池提交callable任务后,我们可能需要一次性获取所有返回结果,有三种处理方法。方法一:自己维护返回结果// 创建一个线程池ExecutorService executorService = Executors.newFixedThreadPool(10);// 存储执行结果的ListList<Future<String>> results = new ArrayList<Future原创 2017-01-17 10:23:36 · 6903 阅读 · 3 评论 -
Java并发编程的艺术(十)——线程池(1)
线程池的作用减少资源的开销 减少了每次创建线程、销毁线程的开销。提高响应速度 每次请求到来时,由于线程的创建已经完成,故可以直接执行任务,因此提高了响应速度。提高线程的可管理性 线程是一种稀缺资源,若不加以限制,不仅会占用大量资源,而且会影响系统的稳定性。 因此,线程池可以对线程的创建与停止、线程数量等等因素加以控制,使得线程在一种可控的范围内运行,不仅能保证系统稳定运行,而且方便性能原创 2017-02-23 15:40:39 · 5679 阅读 · 2 评论 -
Java并发编程的艺术(十一)——线程池(2)
Executor两级调度模型 在HotSpot虚拟机中,Java中的线程将会被一一映射为操作系统的线程。 在Java虚拟机层面,用户将多个任务提交给Executor框架,Executor负责分配线程执行它们; 在操作系统层面,操作系统再将这些线程分配给处理器执行。Executor结构 Executor框架中的所有类可以分成三类:任务 任务有两种类型:Runnable和Callable。原创 2017-02-23 17:34:01 · 4004 阅读 · 3 评论 -
Java并发编程的艺术(十二)——线程安全
什么是『线程安全』?如果一个对象构造完成后,调用者无需额外的操作,可以随意地在多线程环境下使用,并不发生错误,那么这个对象就是线程安全的。线程安全的几种程度线程安全性的前提:对『线程安全性』的讨论必须建立在多线程间存在共享变量这一前提,若对象在多条线程间没有共享数据,那这个对象一定是线程安全的!绝对的线程安全上述线程安全性的定义即为绝对线程安全的情况,即:一个对象构造完之后,调用者无需任何额外的操作原创 2017-02-27 23:03:16 · 3495 阅读 · 2 评论 -
Java并发编程的艺术(十三)——锁优化
自旋锁背景:互斥同步对性能最大的影响是阻塞,挂起和恢复线程都需要转入内核态中完成;并且通常情况下,共享数据的锁定状态只持续很短的一段时间,为了这很短的一段时间进行上下文切换并不值得。原理:当一条线程需要请求一把已经被占用的锁时,并不会进入阻塞状态,而是继续持有CPU执行权等待一段时间,该过程称为『自旋』。优点:由于自旋等待锁的过程线程并不会引起上下文切换,因此比较高效;缺点:自旋等待过程线程原创 2017-02-28 15:17:55 · 4367 阅读 · 1 评论 -
程序员必知的并发编程注意事项
获取单例对象需要保证线程安全,其中的方法也要保证线程安全。单例对象会被多线程共享,因此要保证它是线程安全的,它其中的方法都要保证是线程安全的。工具类、资源驱动类、单例工厂类都要注意这个问题。 创建线程或线程池时请指定有意义的线程名称,方便出错时回溯。 线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。使用线程池的好处是减少在创建和销毁线程上...原创 2018-03-14 09:41:58 · 2131 阅读 · 0 评论