1.单例模式的懒汉式加载
单例模式懒汉式加载的特点:以时间换空间
public class TestSingleton {
private TestSingleton(){
}
private static TestSingleton testSingleton;
public static TestSingleton getInstence(){
if (testSingleton==null) {
testSingleton = new TestSingleton();
System.out.println("进入单例模式的调用实例对象方法");
}
return testSingleton;
}
}
2.多线程的应用调用单例的方法
创建两个线程分别调用TestSingleton类的getInstence()方法:
public class TestThread {
public static void main(String[] args) {
Thread thread01 = new Thread() {
@Override
public void run() {
TestSingleton.getInstence();
}
};
Thread thread02 = new Thread() {
@Override
public void run() {
TestSingleton.getInstence();
}
};
thread01.start();
thread02.start();
}
}
运行结果:偶尔会出现打印两次语句的情况:
进入单例模式的调用实例对象方法
进入单例模式的调用实例对象方法
3. 单例模式的懒汉式创建多个对象的原因:
假如第一个线程进入if (testSingleton==null) {....}
内部还未创建对象的时候被第二个线程抢占资源,然后第二个线程也进入了if (testSingleton==null) {....}
内部,然后两个线程分别创建了一个对象,导致懒汉式的加载在多线程的应用场景会出现创建多个对象的情况。
public static TestSingleton getInstence(){
if (testSingleton==null) {
testSingleton = new TestSingleton();
System.out.println("进入单例模式的调用实例对象方法");
}
return testSingleton;
}
4.解决办法
为单例模式懒汉式的加载获取实例的方法加上synchronized关键字,使其变为同步方法
public class TestSingleton {
private TestSingleton(){
}
private static TestSingleton testSingleton;
public synchronized static TestSingleton getInstence(){
if (testSingleton==null) {
testSingleton = new TestSingleton();
System.out.println("进入单例模式的调用实例对象方法");
}
return testSingleton;
}
}