单例设计模式:保证类在内存中只有一个对象。
如何保证类在内存中只有一个对象?

(1)控制类的创建,不让其他类来创建本类的对象。private
(2)在本类中定义一个本类的对象。
(3)提供公共的访问方式,例如:

public static MyObject getInstance() {
		return myObject;
	}
单例写法两种:

(1)饿汉模式。
(2)懒汉模式。

立即加载/“饿汉模式”

什么是立即加载?立即加载就是使用类的时候已经将对象创建完毕,常见的实现办法就是直接new实例化。而立即加载从中文的语境来看,有,“着急”、“急迫”的含义,所以称为“饿汉模式”。

package unit6;

public class Demo1_Run {
	public static void main(String[] args) {
		MyThread t1 = new MyThread();
		MyThread t2 = new MyThread();
		MyThread t3 = new MyThread();
		t1.start();
		t2.start();
		t3.start();
	}
}

class MyThread extends Thread {
	public void run() {
		System.out.println(MyObject.getInstance().hashCode());
	}
}

class MyObject {
	//立即加载方式==饿汉模式
	private static MyObject myObject = new MyObject();
	private MyObject() {
		
	}
	
	public static MyObject getInstance() {
		//此代码版本为立即加载
		//此版本代码的缺点是不能有其他势力变量
		//因为getInstance()方法没有同步
		//所以有可能出现非线程安全问题
		return myObject;
	}
}

Java多线程20:单例设计模式

延迟加载/“懒汉模式”

什么是延迟加载?延迟加载就是在调用get()方法时实例才被创建,常见的实例办法就是在get()方法中进行new实例化。而延迟加载从中文的语境来看,是“缓慢”、“不急迫”的含义,所以也称为“懒汉模式”。

package unit6;

public class Demo2_Run {
	public static void main(String[] args) {
		Demo2_MyThread t1 = new Demo2_MyThread();
		t1.start();
	}
}

class Demo2_MyThread extends Thread {
	public void run() {
		int integer = Demo2_MyObject.getInstance().hashCode();
		System.out.println(integer);
	}
}

class Demo2_MyObject {
	private static Demo2_MyObject myObject;
	private Demo2_MyObject() {
		
	}
	
	public static Demo2_MyObject getInstance() {
		//延迟加载
		if (myObject != null) {
			
		} else {
			myObject = new Demo2_MyObject();
		}
		return myObject;
	}
}

Java多线程20:单例设计模式

延迟加载/“懒汉模式”的缺点

在多线程的环境中,就会出现取出多个实例的情况,与单例模式的初衷是相背离的。

package unit6;

public class Demo2_Run {
	public static void main(String[] args) {
		Demo2_MyThread t1 = new Demo2_MyThread();
		Demo2_MyThread t2 = new Demo2_MyThread();
		t1.start();
		t2.start();
	}
}

class Demo2_MyThread extends Thread {
	public void run() {
		int integer = Demo2_MyObject.getInstance().hashCode();
		System.out.println(integer);
	}
}

class Demo2_MyObject {
	private static Demo2_MyObject myObject;
	private Demo2_MyObject() {
		
	}
	
	public static Demo2_MyObject getInstance() {
		
		//延迟加载
		if (myObject != null) {
			
		} else {
			try {
				Thread.sleep(10000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			myObject = new Demo2_MyObject();
		}
		return myObject;
	}
}

Java多线程20:单例设计模式

使用静态内置类实现单例模式
package unit6;

public class Demo3_Run {
	public static void main(String[] args) {
		Demo3_MyThread t1 = new Demo3_MyThread();
		Demo3_MyThread t2 = new Demo3_MyThread();
		Demo3_MyThread t3 = new Demo3_MyThread();
		t1.start();
		t2.start();
		t3.start();
		
	}
}

class Demo3_MyThread extends Thread {
	public void run() {
		System.out.println(Demo3_MyObject.getInstance().hashCode());
	}
}

class Demo3_MyObject {
	//内部类
	private static class MyObjectHandler {
		private static Demo3_MyObject myObject = new Demo3_MyObject();
	}
	private Demo3_MyObject() {
		
	}
	
	public static Demo3_MyObject getInstance() {
		return MyObjectHandler.myObject;
	}
}

Java多线程20:单例设计模式

使用static代码块实现单例模式

静态代码块中的代码在使用类的时候就已经执行了,所以可以应用静态代码块的这个特性来实现单例设计模式。

package unit6;

public class Demo4_Run {
	
	public static void main(String[] args) {
		Demo4_MyThread t1 = new Demo4_MyThread();
		Demo4_MyThread t2 = new Demo4_MyThread();
		Demo4_MyThread t3 = new Demo4_MyThread();
		t1.start();
		t2.start();
		t3.start();
	}
}

class Demo4_MyThread extends Thread {
	public void run() {
		for (int i = 0; i < 5; i++) {
			System.out.println(Demo4_MyObject.getInstance().hashCode());
		}
	}
}

class Demo4_MyObject {
	private static Demo4_MyObject instance = null;
	private Demo4_MyObject() {
		
	}
	static {
		instance = new Demo4_MyObject();
	}
	public static Demo4_MyObject getInstance() {
		return instance;
	}
}

Java多线程20:单例设计模式

相关文章: