1, 保证线程安全的三种方法 :
a, 不要跨线程访问共享变量
b, 使共享变量是 final类型的
c, 将共享变量的操作加上同步
2, 一开始就将类设计成线程安全的 , 比在后期重新修复它 ,更容易 .
3, 编写多线程程序 , 首先保证它是正确的 , 其次再考虑性能 .
4, 无状态或只读对象永远是线程安全的 .
5, 不要将一个共享变量裸露在多线程环境下 (无同步或不可变性保护 )
6, 多线程环境下的延迟加载需要同步的保护 , 因为延迟加载会造成对象重复实例化
7, 对于 volatile 声明的数值类型变量进行运算 , 往往是不安全的 (volatile 只能保证可见性 , 不能保证原子性 ).
详见 volatile 原理与技巧中 , 脏数据问题讨论 .
8, 当一个线程请求获得它自己占有的锁时 ( 同一把锁的嵌套使用 ), 我们称该锁为可重入锁 .
在 jdk1.5 并发包中 , 提供了可重入锁的 java 实现 -ReentrantLock.
9, 每个共享变量 , 都应该由一个唯一确定的锁保护 .
创建与变量相同数目的 ReentrantLock, 使他们负责每个变量的线程安全 .
10,虽然缩小同步块的范围 , 可以提升系统性能 .
但在保证原子性的情况下 , 不可将原子操作分解成多个 synchronized块 .
11, 在没有同步的情况下 , 编译器与处理器运行时的指令执行顺序可能完全出乎意料 .
原因是 , 编译器或处理器为了优化自身执行效率 , 而对指令进行了的重排序 (reordering).
12, 当一个线程在没有同步的情况下读取变量 , 它可能会得到一个过期值 , 但是至少它可以看到那个
线程在当时设定的一个真实数值 . 而不是凭空而来的值 . 这种安全保证 , 称之为最低限的安全性 (out-of-thin-air safety)
在开发并发应用程序时 , 有时为了大幅度提高系统的吞吐量与性能 , 会采用这种无保障的做法 .
但是针对 , 数值的运算 , 仍旧是被否决的 .
13, volatile 变量 , 只能保证可见性 , 无法保证原子性 .
详见 volatile原理与技巧
14, 某些耗时较长的网络操作或 IO, 确保执行时 , 不要占有锁 .
15, 发布 (publish) 对象 , 指的是使它能够被当前范围之外的代码所使用 .( 引用传递 )
对象逸出 (escape), 指的是一个对象在尚未准备好时将它发布 .
原则 : 为防止逸出 , 对象必须要被完全构造完后 , 才可以被发布 ( 最好的解决方式是采用同步 )
this 关键字引用对象逸出
例子 : 在构造函数中 , 开启线程 , 并将自身对象 this 传入线程 , 造成引用传递 .
而此时 , 构造函数尚未执行完 , 就会发生对象逸出了 .
16, 必要时 , 使用 ThreadLocal变量确保线程封闭性 (封闭线程往往是比较安全的 , 但一定程度上会造成性能损耗 )
封闭对象的例子在实际使用过程中 , 比较常见 , 例如 hibernate openSessionInView机制 , jdbc的 connection机制 .
17, 单一不可变对象往往是线程安全的 (复杂不可变对象需要保证其内部成员变量也是不可变的 )
良好的多线程编程习惯是 : 将所有的域都声明为 final, 除非它们是可变的
18, 保证共享变量的发布是安全的
a, 通过静态初始化器初始化对象 (jls 12.4.2 叙述 , jvm 会保证静态初始化变量是同步的 )
b, 将对象申明为 volatile 或使用 AtomicReference
c, 保证对象是不可变的
d, 将引用或可变操作都由锁来保护
19, 设计线程安全的类 , 应该包括的基本要素 :
a, 确定哪些是可变共享变量
b, 确定哪些是不可变的变量
c, 指定一个管理并发访问对象状态的策略
20, 将数据封装在对象内部 , 并保证对数据的访问是原子的 .
建议采用 volatile javabean 模型或者构造同步的 getter,setter.
21, 线程限制性使构造线程安全的类变得更容易 , 因为类的状态被限制后 , 分析它的线程安全性时 , 就不必检查完整的程序 .
22, 编写并发程序 , 需要更全的注释 , 更完整的文档说明 .
23, 在需要细分锁的分配时 , 使用 java监视器模式好于使用自身对象的监视器锁 .
前者的灵活性更好 .
Object target = new Object();
// 这里使用外部对象来作为监视器 , 而非 this
synchronized(target) {
// TODO
}
针对 java monitor pattern, 实际上 ReentrantLock的实现更易于并发编程 .
功能上 , 也更强大 .
24, 设计并发程序时 , 在保证伸缩性与性能折中的前提下 , 优先考虑将共享变量委托给线程安全的类 .
由它来控制全局的并发访问 .
25, 使用普通同步容器 (Vector, Hashtable) 的迭代器 , 需要外部锁来保证其原子性 .
原因是 , 普通同步容器产生的迭代器是非线程安全的 .
26, 在并发编程中 , 需要容器支持的时候 , 优先考虑使用 jdk 并发容器
(ConcurrentHashMap, ConcurrentLinkedQueue, CopyOnWriteArrayList...).
27, ConcurrentHashMap, CopyOnWriteArrayList
并发容器的迭代器 , 以及全范围的 size(), isEmpty() 都表现出弱一致性 .
他们只能标示容器当时的一个数据状态 . 无法完整响应容器之后的变化和修改 .
28, 使用有界队列 , 在队列充满或为空时 , 阻塞所有的读与写操作 . ( 实现生产 - 消费的良好方案 )
BlockQueue 下的实现有 LinkedBlockingQueue 与 ArrayBlockingQueue, 前者为链表 , 可变操作频繁优先考虑 , 后者为数组 , 读取操作频繁优先考虑 .
PriorityBlockingQueue 是一个按优先级顺序排列的阻塞队列 , 它可以对所有置入的元素进行排序 ( 实现 Comparator 接口 )
29, 当一个方法 , 能抛出 InterruptedException, 则意味着 , 这个方法是一个可阻塞的方法 , 如果它被中断 , 将提前结束阻塞状态 .
当你调用一个阻塞方法 , 也就意味着 , 本身也称为了一个阻塞方法 , 因为你必须等待阻塞方法返回 .
如果阻塞方法抛出了中断异常 , 我们需要做的是 , 将其往上层抛 , 除非当前已经是需要捕获异常的层次 .
如果当前方法 , 不能抛出 InterruptedException, 可以使用 Thread.currentThread.interrupt() 方法 , 手动进行中断 .
分享到:
相关推荐
Java并发编程实践是Java...通过这些笔记,我们可以了解到Java并发编程中的关键概念和实践,对于理解和编写高效的并发代码具有极大的帮助。在实际开发中,需要根据具体需求灵活应用这些知识,以保证程序的稳定性和性能。
### Java并发编程实践笔记知识点详解 #### 一、保证线程安全的方法 1. **不要跨线程访问共享变量:** 当多个线程共享某个变量时,若其中一个线程修改了该变量,其他线程若没有正确同步,则可能读取到错误的数据。...
### Java并发编程知识点详解 #### 一、线程状态与管理 在Java中,线程具有多种状态,这些状态的变化反映了线程在其生命周期中的不同阶段。理解这些状态及其转换对于编写高效、健壮的并发程序至关重要。 - **NEW**...
这份"Java并发实践-学习笔记"涵盖了这个关键主题,旨在帮助开发者深入理解和掌握Java中的并发机制。以下是对这份笔记可能包含的一些核心知识点的详细阐述: 1. **Java并发基础**:首先,笔记可能会介绍Java并发的...
Java并发编程实践笔记 Java并发编程实践笔记是一份关于Java并发编程的实践笔记,涵盖了多种关于线程安全、并发编程的实践经验和原则。下面是从笔记中总结的知识点: 1. 保证线程安全的三种方法:不要跨线程访问...
这本"Java并发编程学习笔记"可能是作者在深入研究Java并发特性、工具和最佳实践过程中积累的心得体会。下面,我们将根据这个主题,探讨一些关键的Java并发编程知识点。 1. **线程与进程**:在多任务环境中,线程是...
并发实践 Java是一种面向对象的编程语言,由Sun Microsystems于1995年推出。它是一种跨平台的语言,意味着可以在不同的操作系统上运行。Java具有简单、可移植、高性能和安全性等特点,因此被广泛应用于各种领域。 ...
在Java并发编程中,数据的封装与访问控制、线程安全性的考量、同步...以上知识点是从提供的文件内容中提取出的,旨在帮助理解Java并发编程的基础概念和技术实践。掌握这些概念对于开发高效且可靠的并发程序至关重要。
Java并发编程是Java开发中的重要领域,特别是在大型系统和服务器端应用中,高效地利用多核处理器资源,实现高并发性能至关重要。...通过深入学习和实践,开发者可以更好地驾驭Java并发,提升程序的性能和稳定性。
这份机构内训资料,通过“Java并发体系学习思维笔记”,为我们揭示了Java并发编程的核心概念、最佳实践以及常见问题的解决策略。 首先,我们需要理解Java并发的基础,这包括线程的创建与管理。Java提供了两种主要的...
《Java并发编程实践》这本书是Java开发者深入理解并发编程的重要参考。以下是对书中关键知识点的总结: 1. **线程和进程的区别** - **线程**:是程序执行的最小单位,一个进程中可以有多个线程,它们共享同一块...
《狂神说JAVA的所有笔记》是一份全面且深入的JAVA学习资源,包含了JAVA语言的核心概念、进阶技术...通过阅读和实践这份笔记,你将能够系统地学习JAVA,提升编程技能,甚至在解决问题和设计高效代码方面获得新的洞察。
《实战Java高并发程序设计》是一本专注于Java并发编程实践的书籍,试读版提供了前两章的内容,为读者提供了一个初步了解并发编程基础的窗口。在Java领域,并发编程是构建高性能、高效率系统的关键技术,对于软件开发...
Java是一种广泛使用的面向对象的编程语言,以其跨平台性、高效性和丰富的类库而...通过阅读并实践这些笔记,初学者不仅可以掌握Java编程,还能培养良好的编程习惯和思维方式,为日后的深入学习和开发工作打下坚实基础。
JAVA并发编程实践-构建执行程序块-学习笔记 JAVA并发编程实践是指在JAVA编程语言中,使用多线程、并发编程来实现高效、可靠的程序执行。构建执行程序块是指在并发编程中,使用线程安全的类来管理状态,以确保程序的...
总的来说,Java并发编程实践中的任务执行是一个涉及线程调度、线程池管理、任务生命周期控制、结果处理等多个方面的复杂主题。理解和掌握这些概念和技术,能够帮助开发者编写出更加高效、可靠的并发程序。
此外,笔记可能还会涵盖线程与并发,这是Java的一个强项。学习者将了解到线程的基本概念、同步机制(如synchronized关键字、volatile变量、Lock接口)以及并发工具类,如ExecutorService和Semaphore。 对于Java SE...
Java是世界上最流行的编程语言之一,尤其在企业级应用开发领域占据主导地位。这份"java全套培训笔记"来自于加拿大的知名IT培训...通过系统学习和实践,你将能够掌握Java编程的各个方面,从而在IT行业中立足并取得成功。
10. **Java并发编程**:包括线程池、锁机制(如synchronized、ReentrantLock)、并发容器(如ConcurrentHashMap、CopyOnWriteArrayList)以及并发工具类(如CountDownLatch、CyclicBarrier)。 这些是Java基础知识...
Java并发编程实践中的线程池是一个关键的概念,它在多线程编程中扮演着至关重要的角色,有效地管理和调度线程资源,以提高系统的性能和效率。线程池通过复用已存在的线程来减少线程的创建和销毁开销,避免了频繁的上...