设计模式--创建型模式--单例模式
关键点
构造器私有化
公有的静态方法,返回此类的实例
私有静态的此类的实例
应用场景
当想控制实例的数目,节省系统资源时
类似:数据库连接池(连接池只有一个),线程池
案例代码
/**
* 单例模式测试:
* 单例模式的关键点:
* 构造器私有
* 因为构造器私有,所以:必须有唯一的入口访问此类的实例 --> 提供一个公有的静态方法,供别的类访问
* 因为是在静态方法中,所以:必须 有一个私有的当前类的静态变量应用
*
* 懒汉式、饿汉式的区别:
* 关键点在于:对象实例化的时机不同
*
* 为什么饿汉模式,不存在线程安全的问题???
* 因为:在加载类的时候,对象就实例化了(类加载的时候,是单线程???)
*
*
*/
public class SingletonTest {
public static void main(String[] args) {
// 饿汉式单例
for(int i=0; i<10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(HungerSingleton.getInstance());
}
}).start();
}
/*// 非线程安全的 懒汉式单例
for(int i=0; i<10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(UnSafeSingleton.getInstance());
}
}).start();
}*/
/*// 线程安全的 懒汉式单例 - 同步方法
for(int i=0; i<10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SafeSingleton.getInstance());
}
}).start();
}*/
/*// 线程安全的 懒汉式单例 - 同步块
for(int i=0; i<10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SafeSingleton2.getInstance());
}
}).start();
}*/
/*// 线程安全的 懒汉式单例 - Double Check
for(int i=0; i<10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SafeSingleton3.getInstance());
}
}).start();
}*/
/*// enum类型的 懒汉式单例
for(int i=0; i<10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(EnumSingleton.INSTANCE);
System.out.println(EnumSingleton.INSTANCE.toUpperCase("yorick"));
}
}).start();
}*/
}
}
/*===============================饿汉式单例===================================*/
class HungerSingleton {
private static HungerSingleton instance = new HungerSingleton();
private HungerSingleton() {}
public static HungerSingleton getInstance() {
return instance;
}
}
/*===============================懒汉式单例===================================*/
/**
* 懒汉式的单例:非线程安全的
*/
class UnSafeSingleton {
private static UnSafeSingleton instance = null;
private UnSafeSingleton() {}
/**
* 单例方法
* @return
*/
public static UnSafeSingleton getInstance(){
if (instance == null) {
instance = new UnSafeSingleton();
}
return instance;
}
}
/**
* 线程安全的懒汉式单例
* 缺点:
* 性能低:锁的粒度太粗
*/
class SafeSingleton {
private static SafeSingleton instance = null;
private SafeSingleton() {}
public static synchronized SafeSingleton getInstance() {
if (instance == null) {
instance = new SafeSingleton();
}
return instance;
}
}
/**
* 线程安全的懒汉式单例
* 缺点:
* 性能低: 锁的粒度太粗
*/
class SafeSingleton2 {
private static SafeSingleton2 instance = null;
private SafeSingleton2() {}
public static SafeSingleton2 getInstance() {
synchronized (SafeSingleton2.class){
if (instance == null) {
instance = new SafeSingleton2();
}
}
return instance;
}
}
/**
* 线程安全的懒汉式单例
* 缺点:
* 性能低: 锁的粒度相对细
*/
class SafeSingleton3 {
private static SafeSingleton3 instance = null;
private SafeSingleton3() {}
public static SafeSingleton3 getInstance() {
if (instance == null) {
synchronized (SafeSingleton3.class) {
if (instance == null) {
instance = new SafeSingleton3();
}
}
}
return instance;
}
}
/*===============================枚举式单例===================================*/
enum EnumSingleton {
INSTANCE;
public String toUpperCase(String name) {
return name.toUpperCase();
}
}
小小的疑问?
类加载的时候,是单线程进行加载的吗???
本文来自博客园,作者:小小落,转载请注明原文链接:https://www.cnblogs.com/dyorick/p/15538783.html

浙公网安备 33010602011771号