单线程懒汉式
package com.cxq.multiThreadSingleMode;
public class singleMode {
public static void main(String[] args){
for(int i =0;i<10000;i++){
Boss.getBoss();
}
}
}
class Boss{
private Boss(){
System.out.println("一个Boss对象被实例化了!");
}
private static Boss Instance = null;
public static Boss getBoss(){
if(Instance == null){
Instance = new Boss();
}
return Instance;
}
}
输出为:一个Boss对象被实例化了!
单线程环境下懒汉式单例一定不会出问题,这没问题;
多线程环境下的懒汉式(线程不安全)
package com.cxq.multiThreadSingleMode;
public class singleMode {
public static void main(String[] args){
Runnable runnable = new Runnable() {
@Override
public void run() {
Boss.getBoss();
}
};
for(int i =0;i<10000;i++){
new Thread(runnable).start();
}
}
}
class Boss{
private Boss(){
System.out.println("一个Boss对象被实例化了!");
}
private static Boss Instance = null;
public static Boss getBoss(){
if(Instance == null){
Instance = new Boss();
}
return Instance;
}
}
运行结果:
一个Boss对象被实例化了!
一个Boss对象被实例化了!
一个Boss对象被实例化了!
可以看到执行了三次Boss对象的实例化,说明出现了线程不安全的情况;
这时候又出现了临界资源问题,其中有好几个线程在运行过程中获得的Instance为null,所以去执行getBoss方法的时候就会执行多次Instance = new Boss();这就是问题的所在了
解决办法其实很简单,就是我前面博客说的那几种解决办法
synchronized代码块 synchronized函数 ReenreantLock类
饿汉式(单线程、多线程都没问题,线程安全)
class Boss1{
private Boss1(){
System.out.println("一个Boss1对象被实例化了!");
}
private final static Boss1 Instance = new Boss1();
//静态工厂模式
private static Boss1 getInstance(){return Instance;}
}