多线程编程
一枝会思想的芦苇
这个作者很懒,什么都没留下…
展开
-
1.基础:线程的创建、启动与运行
目录1.以定义Thread 类子类的方式创建线程2.以创建Runnable 接口实例的方式创建线程3.两种方式的区别在Java 平台中创建一个线程就是创建一个Thread 类(或其子类)的实例。Thread 类的start 方法的作用是启动相应的线程。运行一个线程实际上就是让Java 虚拟机执行该线程的run 方法,从而使相应线程的任务处理逻辑代码得以执行。Thread 类的两个常用构造器是:...原创 2019-02-15 21:53:44 · 195 阅读 · 0 评论 -
6.JAVA线程同步机制:原子变量类
原子变量类 (Atomics)是基于CAS实现的能够保障对共享变量进行read-modify-write更新操作的原子性和可见性的一组工具类。这里所谓的read-modify-write更新操作,是指对共享变量的更新不是一个简单的赋值操作,而是变量的新值依赖于变量的旧值,例如自增操作 “count++”。由于volatile无法保障自增操作的原子性,而原子变量类的内部实现通常借助一个volatil...原创 2019-02-18 11:14:37 · 229 阅读 · 0 评论 -
5.JAVA轻量级线程同步机制:volatile关键字
目录1.概述2.作用3.典型应用场景1.概述volatile关键字用于修饰共享可变变量,即没有使用final关键字修饰的实例变量或静态变量 ,相应的变量就被称为volatile变量。volatile关键字表示被修饰的变量的值容易变化(即被其他线程更改),因而不稳定 。volatile变量的不稳定性意味着对这种变量的读和写操作都必须从高速缓存或者主内存(也是通过高速缓存读取)中读取,以读取变量的...原创 2019-02-17 22:28:40 · 317 阅读 · 0 评论 -
4.JAVA线程同步机制:锁
目录1.概述分类作用2.内部锁:synchronized1.概述分类按照 Java 虚拟机对锁的实现方式划分,Java 平台中的锁包括内部锁 (Intrinsic Lock)和显式锁 (Explicit Lock)。内部锁是通过synchronized关键字实现的;显式锁是通过java.concurrent.locks.Lock 接口的实现类(如java.concurrent.locks.R...原创 2019-02-17 21:38:41 · 218 阅读 · 0 评论 -
7.JAVA线程同步机制:对象的发布与逸出
目录1.对象发布的几种形式2.static关键字3.final关键字4.安全发布与逸出1.对象发布的几种形式对象发布是指使对象能够被其作用域之外的线程访问。常见的对象发布形式包括以下几种。将对象引用存储到public变量中。例如:public Map<String, Integer> registry = new HashMap<String, Integer>...原创 2019-02-18 12:15:58 · 265 阅读 · 0 评论 -
2.基础:线程的生命周期状态
Java 线程的状态可以使用监控工具查看,也可以通过Thread.getState()调用来获取。Thread.getState() 的返回值类型Thread.State是一个枚举类型(Enum) 。Thread.State 所定义的线程状态包括以下几种。NEW: 一个已创建而未启动的线程处于该状态。由于一个线程实例只能够被启动一次,因此一个线程只可能有一次处于该状态。RUNNABLE: 该状...原创 2019-02-15 22:06:12 · 85 阅读 · 0 评论 -
3.线程安全问题:原子性、可见性、有序性
目录1.原子性2.可见性3.有序性1.原子性对于涉及共享变量访问的操作,若该操作从其执行线程以外的任意线程来看是不可分割的,那么该操作就是原子操作,相应地我们称该操作具有原子性 (Atomicity)。原子操作的“不可分割“包括以下两层含义。访问(读、写)某个共享变量的操作从其执行线程以外的任何线程来看,该操作要么已经执行结束要么尚未发生,即其他线程不会“看到“该操作执行了部分的中间效果。...原创 2019-02-16 23:26:50 · 193 阅读 · 0 评论 -
8.程序并发化的实现方式
目录1.基于数据的分割2.基于任务的分割2.1 按任务的资源消耗属性分割2.2 按处理步骤分割3.合理设置线程数3.1 Amdahl's定律3.2 线程数设置的原则使用分而治之的思想进行多线程编程。首先需要将程序算法中只能串行的部分与可以并发的部分区分开来,然后使用专门的线程(工作者线程)去并发地执行那些可并发化的部分(可并发点)。具体来说,多线程编程中分而治之的使用主要有两种方式:基于数据的分...原创 2019-02-20 13:01:40 · 425 阅读 · 0 评论 -
16.保障线程安全的设计技术:不可变对象
目录1.定义2.不可变对象的典型应用场景1.定义不可变对象 (Immutable Object) 是指一经创建其状态就保持不变的对象。不可变对象也具有固有的线程安全性,因此不可变对象也可以像无状态对象那样被多个线程共享,而这些线程访问这些共享对象的时候无须加锁。当不可变对象所建模的现实实体的状态发生变化时,系统通过创建新的不可变对象实例来进行反映。一个严格意义上的不可变对象要同时满足以下所有...原创 2019-02-25 20:42:01 · 245 阅读 · 0 评论 -
17.保障线程安全的设计技术:线程特有对象
目录1.定义2.使用1.定义对于一个非线程安全对象,每个线程都创建一个该对象的实例,各个线程仅访问各自创建的实例,且一个线程不能访问另外一个线程创建的实例。这种各个线程创建各自的实例,一个实例只能被一个线程访问的对象就被称为线程特有对象,相对应的线程就被称为该线程特有对象的持有线程。2.使用ThreadLocal类相当于线程访问其线程特有对象的代理 (Proxy),即各个线程通过这个对象可...原创 2019-02-25 21:48:41 · 268 阅读 · 0 评论 -
18.保障线程安全的设计技术:装饰器模式
目录1.定义2.优点3.缺点1.定义装饰器 (Decorator) 模式可以用来实现线程安全,其基本思想是为非线程安全对象创建一个相应的线程安全的外包装对象 (Wrapper), 客户端代码不直接访问非线程安全对象而是访问其外包装对象。外包装对象与相应的非线程安全对象具有相同的接口,因此客户端代码使用外包装对象的方式与直接使用相应的非线程安全对象的方式相同,而外包装对象内部通常会借助锁,以线程...原创 2019-02-25 22:08:58 · 266 阅读 · 0 评论 -
9.线程间协作:wait/notify
目录1.wait/notify的作用与用法1.1 wait1.2 notify2. wait/notify的开销及问题3.Object.notify()/notifyAII()的选用1.wait/notify的作用与用法1.1 wait一个线程因其执行目标动作所需的保护条件未满足而被暂停的过程就被称为等待(Wait)。一个线程更新了系统的状态,使得其他线程所需的保护条件得以满足的时候唤醒那些...原创 2019-02-20 21:18:32 · 111 阅读 · 0 评论 -
10.线程间协作:条件变量Condition接口
目录1.Condition的使用2.解决过早唤醒问题3.Condition.awaitUntil(Date deadline)1.Condition的使用Condition接口可作为 wait/notify 的替代品来实现等待/通知,它为解决过早唤醒问题提供了支持,并解决了 Object.wait(long)不能区分其返回是否是由等待超时而导致的问题。Condition 接口定义的 await...原创 2019-02-20 22:07:58 · 172 阅读 · 0 评论 -
11.线程间协作:倒计时协调器CountDownLatch
目录1.使用2.注意问题1.使用工具类CountDownLatch可以用来实现一个(或者多个)线程等待其他线程完成一组特定的操作之后才继续运行。这组操作被称为先决操作。CountDownLatch内部会维护一个用于表示未完成的先决操作数量的计数器 。CountDownLatch.countDown() 每被执行一次就会使相应实例的计数器值减少1。当计数器值不为0时CountDownLatch....原创 2019-02-21 10:47:53 · 193 阅读 · 0 评论 -
12.线程间协作:栅栏CyclicBarrier
目录1.使用2.CyclicBarrier的典型应用场景1.使用有时候多个线程可能需要相互等待对方执行到代码中的某个地方(集合点),这时这些线程才能够继续执行 。JDK 1.5 开始引入了一个类java.util.concurrent.CyclicBarrier, 该类可以用来实现这种等待。使用CyclicBarrier实现等待的线程被称为参与方 (Party)。参与方只需要执行CyclicB...原创 2019-02-21 11:21:15 · 102 阅读 · 0 评论 -
19.保障线程安全的设计技术:并发集合
目录1.并发集合类2.遍历方式1.并发集合类java.util.concurrent 包中引入了一些线程安全的集合对象,它们被称为并发集合。这些对象通常可以作为同步集合的替代品,它们与常用的非线程安全集合对象之间的对应关系如下表所示。ConcurrentLinkedQueue是Queue接口的一个线程安全实现类,它相当于LinkedList(也是 Queue 接口的一个实现类)的线程安全...原创 2019-02-26 19:56:18 · 149 阅读 · 0 评论 -
20.线程的活性故障:死锁
目录1.定义2.死锁产生的条件3.规避死锁的方法4.死锁的恢复1.定义死锁是线程的一种常见活性故障。如果两个或者更多的线程因相互等待对方而被永远暂停(线程的生命周期状态为 BLOCKED 或者 WAITING), 那么我们就称这些线程产生了死锁(Deadlock)。 由于产生死锁的线程的生命周期状态永远是非运行状态,因此这些线程所要执行的任务也永远无法进展。死锁产生的一种典型情形如下图。2...原创 2019-02-26 20:53:11 · 247 阅读 · 0 评论 -
21.线程的活性故障:锁死
目录1.定义2.信号丢失锁死3.嵌套监视器锁死1.定义等待线程由于唤醒其所需的条件永远无法成立,或者其他线程无法唤醒这个线程而一直处于非运行状态(线程并未终止)导致其任务 一直无法进展,那么我们就称这个线程被锁死。2.信号丢失锁死信号丢失锁死是由于没有相应的通知线程来唤醒 等 待线程而使等待线程一直处于等待状态的一种活性故障 。信号丢失锁死的一个典型例子是等待线程在执行Object.wai...原创 2019-02-26 21:04:26 · 253 阅读 · 0 评论 -
22.线程的活性故障:线程饥饿
线程饥饿是指线程一直无法获得其所需的资源而导致其任务一直无法进展的一种活性故障。线程饥饿涉及的线程,其生命周期状态不一定就是 WATING 或者 BLOCKED 状态,其状态也可能是 RUNNING (这说明涉及的线程一直在申请其所需的资源),这时饥饿就演变成活锁。...原创 2019-02-26 21:07:33 · 652 阅读 · 0 评论 -
15.保障线程安全的设计技术:无状态对象
如果一个类的同一个实例被多个线程共享并不会使这些线程存在共享状态, 那么这个类及其任意一个实例就被称为无状态对象。无状态对象不含任何实例变量,且不包含任何静态变量或者其包含的静态变量都是只读的(常量)。一个线程执行无状态对象的任意一个方法来完成某个计算的时候,该计算的瞬时状态(中间结果)仅体现在局部变量和(或)只有当前执行线程能够访问的对象的状态上。因此,一个线程执行无状态对象的任何方法都不会对...原创 2019-02-25 20:19:33 · 151 阅读 · 0 评论 -
14.线程间协作:线程中断机制
目录原创 2019-02-25 19:49:27 · 189 阅读 · 0 评论 -
24.线程管理:线程的未捕获异常与监控
1.UncaughtExceptionHandler接口如果线程的 run 方法抛出未被捕获的异常,那么随着 run 方法的退出,相应的线程也提前终止。对于线程的这种异常终止,如何得知并做出可能的补救动作,例如重新创建并启动一个替代线程呢?JDK 1.5 为了解决这个问题引入了UncaughtExceptionHandler接口。该接口是在 Thread 类内部定义的,它只定义了一个方法:vo...原创 2019-02-27 19:28:50 · 413 阅读 · 0 评论 -
25.线程管理:线程工厂
1.ThreadFactory接口从 JDK 1.5 开始, Java 标准库本身就支持创建线程的工厂方法。Threadfactory 接口是工厂方法模式的一个实例,它定义了如下工厂方法:public Thread newThread (Runnable r)newThread 方法可以用来创建线程,该方法的参数 r 代表所创建的线程需要执行的任务。可以在ThreadFactory. ne...原创 2019-02-27 19:42:48 · 614 阅读 · 0 评论 -
26.线程管理:线程的暂挂与恢复
Thread.suspend()、Thread.resume()这两个方法都是已废弃的方法。其作用分别是暂挂线程和恢复线程。我们可以采用与停止线程相似的思想来实现线程的暂挂与恢复:设置一个线程暂挂标志,线程每次执行比较耗时的操作前都先检查一下这个标志。如果该标志指示线程应该暂挂,那么线程就执行 Object.wait()/Condition.await()暂停,直到其他线程重新设置暂挂标志并将其唤...原创 2019-02-27 20:05:16 · 420 阅读 · 0 评论 -
13.线程间协作:生产者—消费者模式
目录1.生产者—消费者模式2.阻塞队列3.流量控制与信号量4.双缓冲与Exchanger1.生产者—消费者模式在生产者—消费者模式中,生产者 (Producer) 的主要职责是生产(创建)产品(Product)。产品既可以是数据,也可以是任务。消费者 (Consumer) 的主要职责是消费生产者所生产的产品。这里的“消费“包括对产品所代表的数据进行加工处理或者执行产品所代表的任务。生产者和消费...原创 2019-02-23 12:52:29 · 227 阅读 · 0 评论 -
java多线程编程学习资料
Java多线程编程实战指南-核心篇(黄文海著)原创 2019-02-18 12:19:18 · 166 阅读 · 0 评论 -
27.线程管理:线程池
目录1.定义2.ThreadPoolExecutor3.任务的处理结果、异常处理与取消4.线程池监控5.线程池死锁6.工作者线程的异常终止1.定义线程是一种昂贵的资源,其开销有很多方面。因此,从整个系统乃至整个主机的角度来看我们需要一种有效使用线程的方式。线程池就是有效使用线程的一种常见方式。线程池内部可以预先创建一定数量的工作者线程,客户端代码并不需要向线程池借用线程而是将其需要执行的任务...原创 2019-02-27 21:43:44 · 233 阅读 · 0 评论 -
28.JAVA异步编程:Executor框架
目录1.Executor与ExecutorService接口2.实用工具类 Executors3.异步任务的批量执行:CompletionService1.Executor与ExecutorService接口java.util.concurrent.Executor接口是对任务的执行进行的抽象,该接口仅定义了如下方法:void execute(Runnable command)其中,co...原创 2019-02-28 20:29:27 · 681 阅读 · 0 评论 -
29.JAVA异步编程:异步计算助手FutureTask
采用 Runnable 实例来表示异步任务,其优点是任务既可以交给一个专门的工作者线程执行(以相应的 Runnable 实例为参数创建并启动一个工作者线程),也可以交给一个线程池或者 Executor 的其他实现类来执行;其缺点是我们无法直接获取任务的执行结果。使用 Callable 实例来表示异步任务,其优点是我们可以通过 ThreadPooIExecutor. submit(Callable)...原创 2019-02-28 20:51:30 · 207 阅读 · 0 评论 -
30.JAVA异步编程:可重复执行的异步任务AsyncTask类
FutureTask 基本上是被设计用来表示一次性执行的任务,如果同一个对象所表示的任务需要被多次执行,并且我们需要对该任务每次的执行结果进行处理,那么FutureTask 仍然是不适用的,此时我们可以考虑使用抽象异步任务类AsyncTask 来表示这种任务。AsyncTask 抽象类同时实现了 Runnable 接口和 Callable 接口 。 AsyncTask 子类通过覆盖 call 方...原创 2019-02-28 21:05:06 · 976 阅读 · 0 评论 -
31.JAVA异步编程:计划任务
1.ScheduledExecutorService在有些情况下,我们可能需要事先提交一个任务,这个任务并不是立即被执行的,而是要在指定的时间或者周期性地被执行,这种任务就被称为计划任务 (Scheduled Task)。典型的计划任务包括清理系统垃圾数据、系统监控、数据备份等 。ExecutorService 接口的子类 ScheduledExecutorService 接口定义了一组方法用...原创 2019-02-28 21:47:05 · 504 阅读 · 0 评论 -
23.线程的活性故障:活锁
活锁是指线程一直处于运行状态,但是其任务却一直无法进展的一种活性故障。原创 2019-02-26 21:09:03 · 198 阅读 · 0 评论