榆林做网站需要注意的几点,芜湖县住房建设局网站,服装图案素材网站,360应用市场——仅作笔记使用#xff0c;内容多摘自《java并发编程实战》在并发编程中#xff0c;如果状态变量仅在单个线程中初始化和使用#xff0c;自然是线程安全的#xff0c;但一旦涉及到线程间的数据交互#xff0c;如何声明一个用于多线程的单例状态变量才是安全的呢#xf…——仅作笔记使用内容多摘自《java并发编程实战》在并发编程中如果状态变量仅在单个线程中初始化和使用自然是线程安全的但一旦涉及到线程间的数据交互如何声明一个用于多线程的单例状态变量才是安全的呢最容易想到的自然是通过一个工厂函数进行初始化并获取实例对象如下public class Demo {private static Resource resource;public static Resource getInstance() {if(resource null) {resource new Resource();}return resource;}}然而上述的方法存在一个典型的竞态条件在多线程的形况下getInstance可能会返回不同的对象导致不可预知的错误。因此需要进行同步操作public class Demo {private static Resource resource;public synchronized static Resource getInstance() {if(resource null) {resource new Resource();}return resource;}}然而众所周知的是通过同步限制线程同时访问方法会一定程度上影响程序的并发性能于是产生了以下的初始化方法public class Demo {public static Resource resource new Resource();public static Resource getInstance() {return resource;}}因为在初始化器中采用了特殊的方式处理静态域并提供了额外的线程安全性保证。静态初始化器是由JVM在类的初始化阶段执行即在类被加载后并且被线程使用之前。由于JVM在初始化期间将获得一个锁且每个线程都至少获取一次这个锁以确保这个类已经加载故在静态初始化期间内存写入操作将自动对所有的线程可见以及避免数据破坏。简言之类中的静态变量在声明的时候就做初始化可以经由JVM提供线程安全方便的保证而无需自己添加synchronized关键字去进行同步从而减少了线程同步带来的性能消耗。这种初始化方式被称为提前初始化。相对的之前两种初始化方式被称为惰性初始化或者延迟初始化。考虑到有些类的实例在初始化的时候可能会产生比较高的开销故人们希望在需要用到的时候再进行初始化于是结合延迟初始化域JVM初始化静态域的特点产生了较为常用的延迟初始化占位类模式public class Demo {private static class ResourceHolder {public static Resource resource new Resource();}public static synchronized Resource getInstance() {return ResourceHolder.resource;}}因为静态类在使用的时候才会被加载故JVM第一次加载该静态类的时候通过JVM即可实现静态域的线程同步即满足了延迟加载的需求也避开了同步带来的性能消耗。