《Java并发编程实践》笔记
1)父线程VS子线程:JVM要等到所有用户线程都结束后才会终止,或者调用System.exit()方法强制终止JVM。如果只有守护线程在运行,则JVM将会自动终止。在java中,父线程和子线程只是在运行时谁创建谁的关系。一旦线程被启动,这2个线程平等的没有父子关系,父线程一般结束不会影响子线程的运行。
2)线程会共享进程范围内的资源
======================================================================
线程的优势:
1)发挥多处理器的强大功能
2)建模的简单性
如果在程序中只包含一种类型的任务,那么比包含多种不同类型任务的程序要更易于变现,错误更少,也更容易测试。如果为模型中每种类型的任务都分配一个专门的线程,那么可以形成一种串行执行的假象,并将程序的执行逻辑与[调度机制的细节、交替执行的操作、异步I/O、资源等待等问题]分离开来。通过使用线程,可以将负责并且异步的工作流进一步分解为一组简单并且同步的工作流,每个工作流在一个单独的线程中运行,并在特定的同步位置进行交互。【典型例子:Servlet】
3)异步事件的简化处理
4)响应更灵敏的用户界面。【典型例子:Java里的AWT和Swing工具,采用一个事件分发线程代替主事件循环】
线程带来的风险:
1)安全性问题:多个线程共享相同的内存地址空间
2)活跃性问题:如何避免死锁、饥饿、活锁。。。,依赖不同线程的事件发生时序
3)性能问题:线程调度、同步机制带来的性能开销
线程无处不在:
每个Java应用程序都会使用线程。当JVM启动时,它将为JVM的内部任务(例如:垃圾收集、终结操作等)创建后台线程,并创建一个主线程来运行main方法。AWT和Swing的UI框架将创建线程来管理用户界面事件。Timer将创建线程来执行延迟任务。一些组件框架,例如Servlet和RMI,都会创建线程并调用这些线程中的方法。
======================================================================
线程安全性:
1)要编写线程安全的代码,其核心在于要对状态访问操作进行管理,特别是对共享的和可变状态的访问。(共享且可变)【三种方法:①不在线程之间共享该状态变量;②将状态变量修改为不可变的变量;③在访问状态变量时使用同步】
2)Java中的同步机制(多个线程中指令执行前后顺序):synchronized(内置互斥独占加锁)|Object的wait|notify、volatile类型的变量、显式锁|Condition、原子变量(java.util.concurrent.atomic实现在数值和对象引用上的原子状态转换|CAS)、(静态初始化器由JVM在类的初始化阶段执行,由于在JVM内部存在同步机制)。
3)类是线程安全的:当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协助,这个类都能表现出正确地行为。——保证不变性条件不被破坏。
======================================================================
原子、加锁、可见(提交)
3.5)共享数据可见性:多线程安全根本问题所在,多个线程指令执行顺序和多级缓存造成各处变量不一致。所以①从执行顺序开始处理:Java同步机制synchronized、Object的wait|notify、volatile、AbstractQueueSynchronized,其底层是Java内存模型lock—read—load—use—assign—store—write—unlock的各种约定和原则。②是CAS非阻塞,类似一种网络协议[忘了],一直测试直到不产生碰撞冲突后才继续操作。③是ThreadLocal造成不共享。④不变性,使变量不可变就不存在可见性问题。
4)竞态条件:由于不恰当的执行时序而出现不正确的结果。【典型例子:先检查后执行】
5)复合操作:将“先检查后执行”以及“读取-修改-写入”等操作的统称:包含一组必须以原子方式执行的操作以确保线程安全性。 原子性。
6)要保持状态的一致性,就需要在单个原子操作中更新所有相关的状态变量。对于每个包含多个变量的不变性条件,其中涉及的所有变量都需要由同一个锁来保护。
8)重入:获取锁的操作的粒度是“线程”,而不是“调用”——如果某个线程试图获得一个意见由它自己持有的锁,那么这个请求就会成功。【内置锁synchronized是可重入的】
9)虽然synchronized方法可以确保单个操作的原子性,但如果要把多个操作合并为一个复合操作,还是需要额外的加锁机制。
10)加锁的含义不仅仅局限于互斥行为,还包括内存可见性。为了确保所有线程都能看到共享变量的最新值,所有执行读操作或者写操作的线程都必须在同一个锁上同步。——对象的最新状态被安全地发布。【加锁机制既可以确保可见性又可以确保原子性,而volatile变量只能确保可见性】
11)volatile变量:确保将变量的更新操作马上通知到其他线程。【典型例子:检查某个状态标记以判断是否退出循环】。Volatile变量通常用作某个操作完成、发生中断或者状态的标志。但是volatile的语义不足以确保递增操作++的原子性。(原子变量提供了“读-改-写”的原子操作,并且常常用做一种“更好的volatile变量”)
12)“发布”一个对象:是对象能够在当前作用域之外的代码中使用。可以是以下几种情况:①将对象的引用保存到一个公有的静态变量中,以便任何类和线程都能看到该对象;②发布某个对象的时候,在该对象的非私有域中引用的所有对象都会被发布;③发布一个内部的类实例,内部类实例关联一个外部类引用。
13)逸出:某个不应该发布的对象被公布的时候。某个对象逸出后,你必须假设有某个类或线程可能会误用该对象,所以要封装。
14)不要在构造过程中使this引用逸出。【常见错误:在构造函数中启动一个线程。】
======================================================================
15)线程封闭:不共享。仅在单线程内访问数据,就不需要同步。【典型应用:①Swing的可视化组件和数据模型对象都不是线程安全的,Swing通过将它们封闭到Swing的实际分发线程中来实现线程安全;②JDBC的Connection对象】
16)线程封闭技术:①Ad-hoc线程封闭:维护线程封闭性的职责完全由程序实现来承担。I单线程子系统。在volatile变量上存在一个特殊的线程封闭:能确保只有单个线程对共享的volatile变量执行写入操作(其他线程有读取volatile变量),那么就可以安全地在这些共享的volatile变量上执行“读取-修改-写入”的操作,而其他读取volatile变量的线程也能看到最新的值。②栈封闭:通过线程的局部变量,但也要注意不能使之逸出。③ThreadLocal类
17)不变性:如果某个对象在被创建后其状态就不能被修改,那么这个对象就称为不可变对象。线程安全性是不可变对象的固有属性之一,他们的不变性条件是有构造函数创建的。当满足以下所有条件的时候,对象才是不可变的:①对象创建以后起状态就是不能修改;②对象的所有域都是final类型;③对象是正确创建的(在对象的创建期间,this引用没有移除)。
18)任何线程都可以再不需要额外同步的情况下安全的访问不可变对象,即使在发布这些对象时没有使用同步。
18)安全发布:常用模式:要安全的发布一个对象,对象的引用以及对象的状态必须同时对其他线程可见:①在静态初始化函数中初始化一个对象引用(静态初始化器由JVM在类的初始化阶段执行,由于在JVM内部存在同步机制,所以可以安全地发布);②将对象的引用保存到volatile类型的域或者AtomicReferance对象中;③将对象的引用保存到某个正确构造对象的final类型域中;④将对象的引用保存到一个由锁保存的域中(线程安全容器)。
19)事实不可变对象
20)如果对象在构建以后可以修改,那么安全发布只能确保“发布当时”状态的可见性。对于可变对象,不仅在发布对象时需要使用同步,而且在每次对象访问时都需要使用同步来确保后续修改操作的可见性。
======================================================================
21)安全的共享对象:
①线程封闭:线程封闭的对象只能由一个线程拥有,对象被封闭在该线程中,并且只能由这个线程修改。
②只读共享:在没有额外同步的情况下,共享的只读对象可以由多个线程并发访问,但任何线程都不能修改它。共享的只读对象包括不可变对象和事实不可变对象。
③线程安全共享:线程安全的对象在其内部实现同步,因此多个线程可以通过对象的公有接口进行访问而不需要进一步的同步。
④保护对象:被保护的对象只能通过持有特定的锁来访问。包含对象包括封装在其他线程安全对象中的对象,以及已发布的并且由某个特定锁保护的对象。
======================================================================
22)设计线程安全的类
在设计线程安全类的过程中,需要包含以下3个基本要素
①找出构成对象状态的所有变量
②找出约束状态变量的不变性条件
③建立对象状态的并发访问管理策略(同步策略定义如何在不违背对象不变条件或后验条件的情况下对其状态的访问操作进行协同)
23)①由于不变性条件以及后验条件在状态及状态转换上施加了各种约束,因此需要额外的同步与封装。如果某些状态是无效的,那么必须对底层的状态变量进行封装,否则客户代码可能会使对象处于无效状态。如果在某个操作中存在无效的状态转换,那么该操作必须是原子的。②在类中也可能包含多个状态变量的不变条件:这些相关的变量必须在单个原子操作中进行读取或更新。③依赖状态的操作:先验条件
======================================================================
24)阻塞队列可以作为同步工具类,其他类型的同步工具类还包括信号量Semaphore、栅栏Barrier(java.util.concurrent.Exchanger<V>一种双向栅栏,各方在栅栏位置上交换数据,java.util.concurrent.CyclicBarrier,)、闭锁Latch(java.util.concurrent.CountDownLatch,java.util.concurrent.FutureTask<V>)
栅栏:所有线程必须同时到达栅栏位置,才能继续执行;闭锁:用于等待事件,栅栏用于等待其他线程。
分享到:
相关推荐
这本书的读书笔记涵盖了多个关键知识点,旨在帮助读者深入理解Java并发编程的核心概念。 1. **线程和进程的区别** - **线程** 是程序执行的最小单位,一个进程中可以有多个线程同时执行,共享同一块内存空间,通信...
在Java并发编程中,数据的封装与访问控制、线程安全性的考量、同步机制的使用是重要的基础概念和技巧。以下是从给出的文件内容中提取出的详细知识点: 1. 数据封装与访问控制:确保内部私有数据不被轻易访问,并且...
《Java并发编程实战》个人读书笔记,非常详细: 1 简介 2 线程安全性 3 对象的共享 4 对象的组合 5 基础构建模块 6 任务执行 7 取消与关闭 8 线程池的使用 9 图形用户界面应用程序 10 避免活跃性危险 11 性能与可...
《java并发编程实战》读书笔记-第3章-对象的共享,脑图形式,使用xmind8制作 包括可见性、发布与逸出、线程封闭、不可变性、安全发布等内容
《java并发编程实战》读书笔记-第2章-线程安全性,脑图形式,使用xmind8制作 包括引言、线程安全性定义、原子性、加锁机制、使用锁保护状态、活跃性与性能等内容
这本"Java并发编程学习笔记"可能是作者在深入研究Java并发特性、工具和最佳实践过程中积累的心得体会。下面,我们将根据这个主题,探讨一些关键的Java并发编程知识点。 1. **线程与进程**:在多任务环境中,线程是...
《java并发编程实战》读书笔记-第3章-对象的共享,脑图形式,使用xmind8制作 包括线程安全类设计、实例封闭、线程安全性委托、现有线程安全类中添加功能和文档化同步策略等内容
│ Java并发编程.png │ ppt+源码.rar │ 高并发编程第二阶段01讲、课程大纲及主要内容介绍.wmv │ 高并发编程第二阶段02讲、介绍四种Singleton方式的优缺点在多线程情况下.wmv │ 高并发编程第二阶段03讲、...
### Java并发编程实践笔记知识点详解 #### 一、保证线程安全的方法 1. **不要跨线程访问共享变量:** 当多个线程共享某个变量时,若其中一个线程修改了该变量,其他线程若没有正确同步,则可能读取到错误的数据。...
《java并发编程实战》读书笔记-第3章-对象的共享,脑图形式,使用xmind8制作 包括同步容器类、并发容器类、阻塞队列和生产者消费者模式、阻塞和中断方法、同步工具类。最后是构建高效且可伸缩的结果缓存
《Java并发编程的艺术》笔记 第一章 并发编程的挑战 第二章 Java并发机制的底层实现原理 volatile的两条实现原则: 1. Lock前缀指令会引起处理器缓存回写到内存 2. 一个处理器的缓存回写到内存会导致其他...
《Java并发编程实战》是一本深入探讨Java多线程和并发编程的经典著作,它为开发者提供了全面、实用的指导,帮助他们理解和解决并发问题。这本书的中文版使得更多的中国开发者能够受益于其丰富的知识和实践经验。 ...
Java语音项目的资源包括原生的JSAPI、开源库如CMU Sphinx和FreeTTS,商业化的服务如Google Cloud Speech-to-Text API,以及其他框架和工具。通过利用这些资源,您可以开发出功能强大的语音应用程序。Java语音项目的...
并发编程实战》阅读笔记 有关 Java 并发编程~ 别急别急,在重写它啦~,会补充一些新的内容进去,预计 2020/02 完成。 Content Java 并发编程基础 保证线程安全的两个角度 构造安全的并发应用程序 Java 并发高级主题 ...
《实战Java高并发程序设计》是一本专注于Java并发编程实践的书籍,试读版提供了前两章的内容,为读者提供了一个初步了解并发编程基础的窗口。在Java领域,并发编程是构建高性能、高效率系统的关键技术,对于软件开发...
"java高并发.txt"可能是一份文档或笔记,涵盖了Java并发编程的核心概念和技术。它可能详细解释了线程的生命周期、线程安全问题(如数据竞争、活锁、死锁)、并发工具类(如CountDownLatch、CyclicBarrier、Semaphore...
11. **案例分析与实战**:笔记可能包含实际的并发编程案例,帮助读者更好地将理论知识应用到实践中。 通过深入学习这份"Java并发实践-学习笔记",开发者能够提升自己在处理多线程和并发问题上的能力,从而设计出更...
Java并发编程学习笔记 本项目整理自《Java7并发编程实战手册》,感兴趣的话推荐阅读原著 本章内容包括: 线程的创建和运行 线程信息的获取和设置 线程的中断 线程中断的控制 线程的Hibernate和恢复 等待线程的终止 ...
综上所述,这一系列学习笔记涵盖了并发编程的关键概念和实战技巧,包括Java内存模型、线程池、并发容器的使用以及常见数据结构的线程安全问题。通过深入学习这些内容,开发者可以更好地理解和解决多线程环境下的编程...
Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....