设计模式大家都很熟悉,今天来记录下最基础也最简单的单例模式
单例模式分为两类,一是饿汉式,另外就是相对的懒汉式
想来看看饿汉式
常见的实现方式如下:
1 public class SingletonHungry {
2 private static SingletonHungry instance = new SingletonHungry();
3
4 private String token;
5
6 private SingletonHungry() {
7 token = System.currentTimeMillis() + "";
8 }
9
10 public static SingletonHungry getInstance() {
11 return instance;
12 }
13
14 public String getToken() {
15 return token;
16 }
17 }
新增token来验证线程安全
来个线程安全的
public class SingletonHungrySafe {
private static String token;
//jvm加载时会实例化
private static class Holder {
private static SingletonHungrySafe INSTANCE = new SingletonHungrySafe();
}
private SingletonHungrySafe() {
token = System.currentTimeMillis() + "";
}
public static final SingletonHungrySafe getInstance() {
return Holder.INSTANCE;
}
public String getToken() {
return token;
}
}
可以保证在各个线程获取Holder.INSTANCE变量之前完成。在保证线程安全的同时,又可以延迟实例化,并且没有降低并发性接下来看看懒汉式,相对的,懒汉式是用时才加载,延后性。先来个线程不安全的
public class SingletonLazy {
private static SingletonLazy instance;
private SingletonLazy() {
}
public static SingletonLazy getInstance() {
if (instance == null) {
instance = new SingletonLazy();
}
return instance;
}
}
线程安全的
public class SingletonLazySafe {
private volatile static SingletonLazySafe instance;
private SingletonLazySafe() {
}
public static SingletonLazySafe getInstance() {
if (null == instance) {
synchronized (SingletonLazySafe.class) {
if (null == instance) {
instance = new SingletonLazySafe();
}
}
}
return instance;
}
}
双重检查加锁,保证线程安全。同时,我们可以对这些进行测试
public class SingletonTest {
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 1000; i++) {
Single single = new Single();
single.start();
}
}
static class Single extends Thread {
@Override
public void run() {
checkSingleHungry();
}
}
private static void checkSingleHungrySafe() {
SingletonHungrySafe singletonHungrySafe = SingletonHungrySafe.getInstance();
System.out.println("Thread id=" + Thread.currentThread().getId() + "token:" + singletonHungrySafe.getToken());
}
private static void checkSingleHungry() {
SingletonHungry singletonHungry = SingletonHungry.getInstance();
System.out.println("Thread id=" + Thread.currentThread().getId() + "token:" + singletonHungry.getToken());
}
}
验证线程安全问题
来源:https://www.cnblogs.com/xzshare/p/12239942.html