【基础普及】
操作系统的发展使得多个程序能够同时运行,程序在各自的进程(processes)中运行:相互分离,各自独立执行,由操作系统来分配资源,比如内存、文件句柄、安全证书。如果需要的话,进程会通过一些原始的机制相互通信:Socket、信号处理(signal handlers)、共享内存(shared memory)、信号量和文件。
自增操作(++i) 是3个离散操作的简写过程:获取当前值 、加1、写回当前值。这是一个“读-改-写(read-update-write)”操作的实例。
惰性初始化(lazy initialization)目的就是延迟对象的初始化,直到程序真正使用它,同时确保它只初始化一次。
线程安全的定义要求是无论是多线程中的时许或交替操作,都保证不破坏那些不可变约束。当一个不变约束包含多个多个变量时,变量间不是彼此独立的;某个变量的值会制约其他几个变量的值。因此更新一个变量时,要在同一个原子操作中更新其他几个。
共享对象
重排序现象:在单个线程中,只要重排序不会对结果产生影响,那么就不能保证其中的操作一定按照程序写定的顺序执行----即使重排序对于其他线程来说会产生明显的影响。
发布(publishing)一个对象的意思是使它能够被当前范围之外的代码所使用。如果变量发布了内部状态,就可能危及到封装性,并使程序难以维持稳定;如果发布对象时,它还没有完成构造,同样危及线程安全。一个对象在尚未准备好时就将它发布,这种情况称作逸出(escape)。
最常见的发布对象的方式就是将对象的引用存储到公共静态域中。任何类和线程都能看见这个域。发布一个对象,同样也发布了该对象所有非私有域的引用链,和方法调用链中的可获得对象也都会被发布。
没有正确的构建:this引用在构造函数完成之前不会从线程中逃逸。只要构造函数结束前没有其他线程使用this引用,this引用就可以通过构造函数存储到某处。
Ad-hoc (非正式的)线程限制是指维护线程限制性的任务全部落在实现上的这种情况。因为没有可见性修饰符与本地变量等语言特性协助将对象限制在目标线程上,所以这种方式是非常容易出错的。
==================================================================================================
【构建块】
在实践中,委托是创建线程安全类最有效的方法之一,只需要用已有的线程安全类来管理所有状态变量即可。