《Java核心技术(卷1)》笔记:第12章 并发
线程
- (P 552)多进程和多线程的本质区别:每一个进程都拥有自己的一整套变量,而线程共享数据 
- (P 555)线程具有6种状态: - New(新建):使用new操作符创建线程时
- Runnable(可运行):调用start方法
- Blocked(阻塞)
- Waiting(等待)
- Timed waiting(计时等待)
- Terminated(终止):run方法正常退出、没有捕获异常
  
- New(新建):使用
- (P 558) - interrupt方法用来请求终止一个线程。当对一个线程调用- interrupt方法时,就会设置线程的中断状态。每个线程都应该不时地检查这个标志,以判断线程是否被中断
- (P 559)如果线程被阻塞,就无法检查中断状态,因此引入 - InterruptedException异常。当在一个被- sleep或- wait调用阻塞的线程上调用- interrupt方法时,那个阻塞调用将被一个- InterrupedtException异常中断
- (P 559)如果设置了中断状态,此时倘若调用 - sleep方法,它不会休眠。实际上,它会清除中断状态并抛出- InterruptedException。因此,如果循环里调用了- sleep,不要检测中断状态,而应当捕获- InterruptedException异常
- (P 560) - interrupted、- isInterrupted以及- interrupt方法的区别:- 方法 - 性质 - 作用 - 影响 - interrupted- Thread的静态方法- 检查当前线程是否被中断 - 会清除该线程的中断状态 - isInterrupted- Thread的实例方法- 测试线程是否被中断 - 不会改变中断状态 - interrupt- Thread的实例方法- 向线程发送中断请求 - 会设置线程的中断状态 
- (P 561)守护线程:唯一用途是为其他线程提供服务,当只剩下守护线程时,虚拟机就会退出。可通过 - setDaemon方法将线程设为守护线程
- (P 561)线程的 - run方法不能抛出任何检查型异常,在线程死亡之前,异常会传递到一个用于处理未捕获异常的处理器(必须实现- Thread.UncaughtExceptionHandler接口)- 方法 - 性质 - 作用 - setUncaughtExceptionHandler- Thread的实例方法- 为任何线程安装一个处理器 - setDefaultUncaughtExceptionHandler- Thread的静态方法- 为所有线程安装一个默认的处理器 
同步
- (P 568)Java提供的两种可防止并发访问代码块的机制: - synchronized关键字
- ReentrantLock类(重入锁)- myLock.lock(); // 一个ReentrantLock对象
 try {
 ...
 } finally {
 myLock.unlock(); // 必须放在finally里,不能使用try-with-resources
 }
 
 
- (P 570)重入(reentrant)锁:线程可以反复获得已拥有的锁,被一个锁保护的代码可以调用另一个使用相同锁的方法。注意确保临界区中的代码不要因为抛出异常而跳出临界区 
- (P 572)一个锁对象可以有一个或多个相关联的条件对象,可以使用 - newCondition方法获得一个条件对象。- 方法 - 性质 - 作用 - newCondition- ReentrantLock的实例方法- 获得一个条件对象 - await- Condition的实例方法- 当前线程现在暂停,并放弃锁 - signalAll- Condition的实例方法- 解除等待这个条件的所有线程的阻塞状态 - signal- Condition的实例方法- 随机选择一个线程解除其阻塞状态 - 使用形式: - class A {
 private var lock = new ReentrantLock();
 private Condition condition;
 ... private A() {
 ...
 condition = lock.newCondition();
 } private someMethod() {
 lock.lock();
 try {
 ...
 while(!(OK to proceed)) { // await调用通常放在循环中
 condition.await();
 }
 ...
 condition.signalAll(); // signalAll只是通知等待的线程:现在有可能满足条件,值得再次检查条件
 // 只要一个对象的状态有变化,而且可能有利于等待的线程,就可以调用signalAll
 // signalAll只是解除等待线程的阻塞,使这些线程可以在当前线程释放锁之后竞争访问对象
 } finally {
 lock.unlock();
 }
 } ...
 }
 
- (P 576)Java中的每个对象都有一个内部锁(只有一个关联条件)。如果一个方法声明时有 - synchronized关键字,那么对象的锁将保护整个方法- 方法 - 性质 - 作用 - 等价于 - wait- Object的实例方法- 将一个线程增加到等待集中 - await- notify/- notifyAll- Object的实例方法- 解除等待线程的阻塞 - signal/- signalAll
- (P 577)将静态方法声明为同步也是合法的,如果调用这样一个方法,它会获得相关类对象( - Class对象)的内部锁
- (P 577)内部锁和条件存在一些限制: - 不能中断一个正在尝试获得锁的线程
- 不能指定尝试获得锁时的超时时间
- 每个锁仅有一个条件可能是不够的
 
- (P 579)同步块: - synchronized(obj) { // 会获得obj对象的锁
 ...
 }
 
- (P 580)监视器的特性: - 监视器是只包含私有字段的类
- 监视器类的每个对象有一个关联的锁
- 所有方法有这个锁锁定
- 锁可以有任意多个相关联的条件
 
- (P 581) - volatile关键字为实例字段的同步访问提供了一种免锁机制,- volatile变量不能提供原子性- 另一种安全访问共享字段的情况:将字段声明为final
 
- 另一种安全访问共享字段的情况:将字段声明为
- (P 582) - java.util.concurrent.atomic包中有很多类使用了很高效的机器级指令来保证其他操作的原子性
- (P 586)线程局部变量: - ThreadLocal- public static final ThreadLocal<SimpleDateFormat> dataFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
 // 在一个给定线程中首次调用get时,会调用构造器中的lambda表达式
 // 在此之后,get方法会返回属于当前线程的那个实例
 String dateStamp = dataFormat.get().format(new Date());
 
线程安全的集合
- (P 589)阻塞队列(blocking queue): - add、- element、- offer、- peek、- poll、- put、- remove、- take
- (P 595)高效的映射、集和队列: - java.util.concurrent包提供了- ConcurrentHashMap、- ConcurrentSkipListMap、- ConcurrentSkipListSet、- ConcurrentLinkedQueue
- (P 602)同步包装器(synchronization wrapper):任何集合类都可以通过使用同步包装器变成线程安全的 - List<E> synchArrayList = Collections.synchronizedList(new ArrayList<E>());
 Map<K, V> synchHashMap = Collections.synchronizedMap(new HashMap<K, V>());
 
线程池
- (P 603) - Callable与- Runnable类似,但是有返回值,只有一个- call方法
- (P 604) - Future保存异步计算的结果
- (P 604)执行 - Callable的一种方法是使用- FutureTask,它实现了- Future和- Runnable接口- Callable<Integer> task = ...;
 var futureTask = new FutureTask<Integer>(task);
 var t = new Thread(futureTask); // it's a Runnable
 t.start();
 ...
 Integer result = futureTask.get(); // it's a Future
 
- (P 605)执行器( - Executors)类有许多静态工厂方法,用来构造线程池
- (P 606)使用线程池时所做的工作: - 调用Executors类的静态方法newCachedThreadPool或newFixedThreadPool
- 调用submit提交Runnable或Callable对象
- 保存好返回的Future对象,以便得到结果或者取消任务
- 当不想再提交任何任务时,调用shutdown
 
- 调用
- (P 607)控制任务组 - 方法 - 性质 - 作用 - 备注 - invokeAny- ExecutorService的实例方法- 提交一个 - Callable对象集合中的所有对象,并返回某个已完成任务的结果- invokeAll- ExecutorService的实例方法- 提交一个 - Callable对象集合中的所有对象,并返回表示所有任务答案的一个- Future对象列表- 这个方法会阻塞,直到所有任务都完成 
- (P 612)fork-join框架:专门用来支持计算密集型任务,假设有一个处理任务,它可以很自然地分解为子任务 
异步计算
- (P 615)CompletableFuture类实现了Future接口,它提供了获得结果的另一种机制。你要注册一个回调,一旦结果可用,就会(在某个线程中)利用该结果调用这个回调(与之不同的是,Future中的get方法会阻塞)
- (P 615)Supplier<T>与Callable<T>:都描述了无参数而且返回值类型为T的函数,不过Supplier函数不能抛出检查型异常
进程
- (P 628)Process类在一个单独的操作系统进程中执行一个命令,允许我们与标准输入、输出和错误流交互。ProcessBuilder类则允许我们配置Process对象
- (P 631)ProcessHandle接口:要获得程序启动的一个进程的更多信息,或者想更多地了解你的计算机上正在运行的任何其他进程,可以使用ProcessHandle接口
- (P 631)得到ProcessHandle的4种方式:- 给定一个Process对象p,p.toHandle()会生成它的ProcessHandle
- 给定一个long类型的操作系统进程ID,ProcessHandle.of(id)可以生成这个进程的句柄
- Process.current()是运行这个java虚拟机的进程句柄
- ProcessHandle.allProcesses()可以生成对当前进程可见的所有操作系统进程的- Stream<ProcessHandle>
 
- 给定一个
《Java核心技术(卷1)》笔记:第12章 并发的更多相关文章
- java中的数据类型,运算符,字符串,输入输出,控制流,大数值,数组; 《java核心技术卷i》 第三章:java基本程序结构;
		<java核心技术卷i> 第三章:java基本程序结构: 每次看书,去总结的时候,总会发现一些新的东西,这次对于java的数组有了更深的了解: java中的数据类型,运算符,字符串,输入输 ... 
- Java核心技术卷一基础知识-第12章-泛型程序设计-读书笔记
		第12章 泛型程序设计 本章内容: * 为什么要使用泛型程序设计 * 定义简单泛型类 * 泛型方法 * 类型变量的限定 * 泛型代码和虚拟机 * 约束与局限性 * 泛型类型的继承规则 * 通配符类型 ... 
- Java核心技术卷阅读随笔--第3章【Java 的基本程序设计结构】
		Java 的基本程序设计结构 现在, 假定已经成功地安装了 JDK,并且能够运行第 2 章中给出的示例程序.我们从现在开始将介绍 Java 应用程序设计.本章主要介绍程序设计的基本概念(如数据类型.分 ... 
- Java核心技术卷阅读随笔--第2章【Java 程序设计环境】
		Java 程序设计环境 本章主要介绍如何安装 Java 开发工具包( JDK ) 以及如何编译和运行不同类型的程序: 控制台程序. 图形化应用程序以及 applet.运行 JDK 工具的方法是在终端窗 ... 
- Java核心技术卷阅读随笔--第4章【对象与类】
		对 象 与 类 4.1 面向对象程序设计概述 面向对象程序设计(简称 OOP) 是当今主流的程序设计范型, 它已经取代了 20 世纪 70 年代的" 结构化" 过程化程序设计开发技 ... 
- Java核心技术卷1Chapter7笔记 图形程序设计
		Swing是指被绘制的用户界面类,AWT是指像事件处理这样的窗口工具箱的底层机制. SWT,JavaFX是可能的代替技术. 创建框架 在Java中,顶层窗口(就是没有包含在其他窗口中的窗口)被称为框架 ... 
- 《Java核心技术卷I》——第5章 继承
		在C++中,没有提供用于表示抽象类的特殊关键字.只要有一个纯虚函数,这个类就是抽象类. hashCode()方法是定义在Object类中,因此每个对象都有一个默认的散列码,其值为对象的存储地址. 绝大 ... 
- 《Java核心技术卷I》——第3章 Java的基本程序设计结构
		byte和short类型主要用于特定的应用场合,例如,底层的文件处理或者需要控制占用存储空间量的大数组. 十六进制数值有一个前缀0x(如0xCAFE),八进制有一个前缀0,如010对应八进制中的8.很 ... 
- 《Java编程思想》笔记 第二十一章 并发
		1.定义任务 实现Runnable 接口的类就是任务类(任务类不一定是实现Runnable接口的类). 实现Runnable 接口,重写run()方法,run方法的返回值只能是 void 任务类就是表 ... 
- Java编程思想读书笔记--第21章并发
		1.基本的线程机制 定义任务 public class LiftOff implements Runnable{ protected int countDown = 10; private stati ... 
随机推荐
- Show information of directory or disk
			There are so many commands of Ubuntu, we just need to know useful and high-frequency commands. I hav ... 
- web CSS3 实现3D动态翻牌效果
			使用纯CSS3 实现翻牌效果 需要注意要给子盒子使用绝对定位,这样两个盒子可以完全重合在一起,需要给父盒子一个 transform-style: preserve-3d;让子盒子翻转时保持3D效果, ... 
- Angular 懒加载找不到模块问题解决方法
			问题: 懒加载无法找到模块 解决办法: 在app-routing.module.ts中引入该模块 
- Keras之对鸢尾花识别
			Keras之队鸢尾花识别 任务目标 对鸢尾花数据集分析 建立鸢尾花的模型 利用模型预测鸢尾花的类别 环境搭建 pycharm编辑器搭建python3.* 第三方库 numpy pandas sklea ... 
- canvas学习01
			canvas 必须指定宽高,确定可绘图区域的大小 canvas标签里写的是浏览器不支持canvas时展示的内容 <canvas id="drawing" width=&quo ... 
- PHPSTORM  Live-Templates变量速查表
			camelCase(String) 返回字符串作为参数传递,转换为驼峰式大小写.例如, my-text-file/my text file/my_text_file将转化为 myTextFile. c ... 
- 朝阳大妈也能听懂的git教程  (好人不谢)
			1 核心概念(非常简单) 分支 同一个树关节 长两个分叉 每一个树关节 就是一个commit commit 是纵向纬度的版本 分支(branch) 是横向纬度的版本 (发挥想象力 自己 ... 
- MacOS SVN简单入门
			背景:MacOS内置了SVN的客户端和服务器端的软件,下边所使用到的目录需要结合自己电脑的具体情况进行设置,并不是很困难. MacOS SVN简单入门 第一部分,创建本地的SVN测试仓库,并修改相应的 ... 
- Python Tuple(元组) min()方法
			描述 Python 元组 min() 函数返回元组中元素最小值.高佣联盟 www.cgewang.com 语法 min()方法语法: min(tuple) 参数 tuple -- 指定的元组. 返回值 ... 
- Skill 脚本演示 ycSetNetColor.il
			https://www.cnblogs.com/yeungchie/ ycSetNetColor.il 将原理图中某一 netName 的所有连线同时修改为一种 颜色 / 线宽. 回到目录 
