懒汉式(线程不安全)

1). 起到了懒加载的效果,但是只能在单线程下使用。

2). 如果在多线程下,一个线程进入了if(null == instance)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例,所以在多线程环境下不可使用这种方式。

3). 结论,在实际开发中,不要使用如下这种方式。

public class SingletonTest03 {
	public static void main(String[] args){
		//Singleton1 s1 = Singleton1.getSingleton1();
		//Singleton1 s2 = Singleton1.getSingleton1();
		
		// s1, s2是同一个实例
		//System.out.println(s1 == s2);
		//System.out.println(s1.hashCode()+"  "+s2.hashCode());
		
		T t1 = new T();
		new Thread(t1).start();
		
		T t2 = new T();
		new Thread(t2).start();
	}
}

class T implements Runnable{

	public Singleton1 s1 = null;
	@Override
	public void run() {
		try {
			Thread.sleep(10000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Singleton1 s1 = Singleton1.getSingleton1();
		System.out.println(s1.hashCode());
	}
}

// 懒汉式(线程不安全)
class Singleton1{
	// 构造器私有化,外部不能new
	private Singleton1(){
		
	}
	
	private static Singleton1 instance;

	// 向外部暴露一个静态的公共方法,当使用到该方法时,才去创建instance
	// 即懒汉式
	public static Singleton1 getSingleton1(){
		if(null == instance){
			instance = new Singleton1();
		}
		return instance;
	}
}

 

 懒汉式(线程安全, 同步方法)

  优缺点:

    1). 解决了线程不安全问题.

    2). 效率太低了,每个线程在想获得类的实例时候,执行getSingleton1()方法都要进行同步,而其实这个方法只执行一次实例化代码就够了,后面的想获得该类实例,直接return就行了,方法进行同步效率太低。

    3). 结论: 在实际开发中,不推荐使用这种方式。

public class SingletonTest04 {
	public static void main(String[] args){
		//Singleton1 s1 = Singleton1.getSingleton1();
		//Singleton1 s2 = Singleton1.getSingleton1();
		
		// s1, s2是同一个实例
		//System.out.println(s1 == s2);
		//System.out.println(s1.hashCode()+"  "+s2.hashCode());
		
		T t1 = new T();
		new Thread(t1).start();
		
		T t2 = new T();
		new Thread(t2).start();
		System.out.println(t1.s1 == t2.s1);
	}
}

class T implements Runnable{

	public Singleton1 s1 = null;
	@Override
	public void run() {
		try {
			Thread.sleep(10000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Singleton1 s1 = Singleton1.getSingleton1();
		System.out.println(s1.hashCode());
	}
}

// 懒汉式(线程安全, 同步方法)
class Singleton1{
	// 构造器私有化,外部不能new
	private Singleton1(){
		
	}
	
	private static Singleton1 instance;

	// 向外部暴露一个静态的公共方法,当使用到该方法时,才去创建instance
	// 即懒汉式
	// 加入了同步代码,解决线程不安全问题
	public static synchronized Singleton1 getSingleton1(){
		if(null == instance){
			instance = new Singleton1();
		}
		return instance;
	}
}

 懒汉式(线程安全, 同步代码块)

   同步代码块这种方法连线程安全问题都解决不了,这种同步并不能起到线程同步的作用。假如一个线程进入了if(null == instance)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例

public class SingletonTest05 {
	public static void main(String[] args){
		//Singleton1 s1 = Singleton1.getSingleton1();
		//Singleton1 s2 = Singleton1.getSingleton1();
		
		// s1, s2是同一个实例
		//System.out.println(s1 == s2);
		//System.out.println(s1.hashCode()+"  "+s2.hashCode());
		
		T t1 = new T();
		new Thread(t1).start();
		
		T t2 = new T();
		new Thread(t2).start();
		System.out.println(t1.s1 == t2.s1);
	}
}

class T implements Runnable{

	public Singleton1 s1 = null;
	@Override
	public void run() {
		try {
			Thread.sleep(10000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Singleton1 s1 = Singleton1.getSingleton1();
		System.out.println(s1.hashCode());
	}
}

// 懒汉式(线程安全, 同步方法)
class Singleton1{
	// 构造器私有化,外部不能new
	private Singleton1(){
		
	}
	
	private static Singleton1 instance;

	// 向外部暴露一个静态的公共方法,当使用到该方法时,才去创建instance
	// 即懒汉式
	// 加入了同步代码,解决线程不安全问题
	public static  Singleton1 getSingleton1(){
		
		if(null == instance){
			synchronized(Singleton1.class){
				instance = new Singleton1();
			}
		}
		return instance;
	}
}