概述
-
-
- 一、恶汉模式
- 二、懒汉模式-非线程安全
- 三、懒汉模式-线程安全
- 四、懒汉模式-双检锁
- 五、静态内部类
- 六、枚举类
- 七、参考文章
-
一、恶汉模式
在这个类还没有使用到的时候就已经创建好了
public class Singleton{
/**
*类变量在类准备阶段就初始化了然后放在<clinit>构造方法中,
*一旦外部调用了静态方法,那么就会初始化完成。
*/
private static Singleton instance = new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return instance;
}
}
二、懒汉模式-非线程安全
在需要获取Singleton对象的时候才去创建这个对象
public class Singleton{
private static Singleton instance = null;
private Singleton(){
}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
三、懒汉模式-线程安全
当两个线程同时执行到判断这个Singleton的实例instance是否为空的时候,两个线程都判断为空,那么这个时候就会返回两个实例,这样一来就不是单例模式了。因此我们想到在方法上进行加锁。
public class Singleton{
private static Singleton instance = null;
private Singleton(){
}
public synchronized static
Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
这个方式的使得一个线程等待的时候过程,降低并发性能。因此想到使用下面的方法
四、懒汉模式-双检锁
public class Singleton{
private static Singleton instance = null;
private Singleton(){
}
public static
Singleton getInstance(){
if(instance == null){
synchronized(Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
我们使用synchronized这个关键字将锁住一个代码块,一旦一个线程获得了这个对象锁,那么另一个线程就只能等待。当一个线程构造实例完成以后,另一个线程就进入判断条件会发现我们的实例初始化过了,不再为null。此时返回实例对象。
五、静态内部类
恶汉模式利用虚拟机加载类的特性初始化实例对象,而懒汉模式则是在类被使用的时候才会被初始化。静态内部类,当我们的类在加载的时候不会执行,只是在类被外界使用的时候才会被初始化。因此这种方式既实现了延迟加载又实现了线程安全。(这里会不会出现安全泄漏问题)
public class Singleton{
private static Singleton instance = null;
static{
instance = new Singleton();
}
private Singleton(){
}
public static
Singleton getInstance(){
return Singleton.instance;
}
}
测试代码
package JingDongProgram;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class Test8 {
public static void main(String[] args){
Callable<Singleton> t1 = new Thread8();
FutureTask<Singleton> f1 = new FutureTask<Singleton>(t1);
Callable<Singleton> t2 = new Thread9();
FutureTask<Singleton> f2 = new FutureTask<Singleton>(t1);
new Thread(f1).start();
new Thread(f2).start();
}
}
class Thread8 implements Callable{
@Override
public Object call() throws Exception {
System.out.println(Singleton.getInstance());
return null;
}
}
class Thread9 implements Callable{
@Override
public Object call() throws Exception {
System.out.println(Singleton.getInstance());
return null;
}
}
输出结果
JingDongProgram.Singleton@2410eb3b
JingDongProgram.Singleton@2410eb3b
六、枚举类
public enum Singleton{
INSTANCE;
}
七、参考文章
https://segmentfault.com/a/1190000010755849
最后
以上就是喜悦向日葵为你收集整理的Java多线程--单例模式的五种实现的全部内容,希望文章能够帮你解决Java多线程--单例模式的五种实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复