最近在复习、整理之前学习的多线程的知识,本着燃烧自己,照亮他人的想法,把自己整理的一些关于多线程的学习笔记、心得分享给大家.
博主准备把自己关于多线程的学习笔记写成三个部分分享给大家: 基础、实战、测试&优化
这三个部分是一环扣一环的.
1.基础: 多线程操作的对象必须是线程安全的,所以构建线程安全的对象是一切的基础.这一部分讲的就是如何构建线程安全的类,和一些多线程的基础知识.
2. 实战: 构建好了线程安全的类,我们就可以用线程/线程池,去构建我们的并发程序了,如何执行任务?如何关闭线程池?如何扩展线程池?这里都会给你答案
3. 测试&优化: 构建好的程序会不会发生死锁? 如何优化程序? 如何知道运行的结果是否正确? 这一部分会 一 一为你解答.
好了废话不多说,本篇博客是系列的第一篇,我们来讲述一下线程安全.
线程安全
在多线程环境下,保证线程访问的数据的安全格外重要.编写线程安全的代码,本质上就管理状态的访问,而且通常是共享的、可变的状态.
状态:可以理解为对象的成员变量.
共享: 是指变量可以被多个线程访问
可变: 是指变量的值在生命周期内可以改变.
保证线程安全就是要在不可控制的并发访问中保护数据.
如果对象在多线程环境下无法保证线程安全,就会导致脏数据和其他不可预期的后果
有很多在单线程环境下运行良好的代码,在多线程环境下却有问题.例如自增操作:
public class Increment { private int num = 0; public void doSomething(){ //do something num++; } }每次调用doSomething()方法的时候,num都会执行自增操作.但是在多线程环境下,这段代码是有问题的.
原因在于num++并不是原子操作,而是由三个离散操作组合而来的:"读-改-写",读取当前的值,加1,写入变量.
可能会出现某一时刻,两个线程同时读到num的数值,然后分别+1,分别写入.这样其中一次计数就不存在了.
有一个专门形容这类情况的名词,叫竞争条件
当计算的正确性依赖于运行时相关的时序或者多线程的交替时,会产生竞争条件.
我对竞争条件的理解就是,多个线程同时访问一段代码,因为顺序的问题,可能导致结果不正确,这就是竞争条件.
"检查-再运行",也是一种竞争条件.
public class Singleton { private Singleton singleton; private Singleton() { } public Singleton getSingleton

