网上可以找到很多种Singleton的实现方式,这些方式要解决的问题主要包括以下几方面:
- 线程安全
- 序列化
- 延迟加载下的线程安全
这个链接解释了这些问题的解决方法,http://www.blogjava.net/kenzhh/archive/2016/03/28/357824.html。
关于volatile关键字,主要有以下作用:
- 保证多线程环境下共享变量的可见性(visibility),就是用volatile修饰的变量,在不同的cpu core进行处理的时候会保证cpu高速缓存和主内存之间的及时同步。对变量的修改会立即同步到主内存。所有的变量的读取都从主内存发生。
- 从JDK1.5开始,如果线程A修改了volatile变量,线程B之后读取该变量,那么在线程A修改之前对线程A可见的变量,在线程B读取volatile变量之后,对线程B也都可见。
- 同样从JDK1.5开始,读取和修改volatile变量的顺序不会被JVM打乱(JVM会为了提升性能在编译时会打乱指令的顺序),修改和读取volatile变量之前或者之后的指令可以被打乱,但是跟随在修改和读取之后的指令会保证在修改和读取之后,而不会跟这些指令混在一起。
Java Volatile Keyword
http://tutorials.jenkov.com/java-concurrency/volatile.html
这篇文章详细介绍了volatile关键字的使用。并且解释了,在多个线程同时对共享的volatile变量进行读写时,volatile是不能保证线程安全的,这时候就必须对变量使用synchronized关键字进行同步。或者使用java.util.concurrent.atomic包下的类达到线程安全的目的。
http://jpbempel.blogspot.com/2013/05/volatile-and-memory-barriers.html
这篇文章介绍了,volatile关键字和memeory barrier,说明了为什么java.util.concurrent.atomic下的类可以实现线程安全,以及为什么使用lazySet()可以提升性能。