package www.tread.com;
/**
* 单例模式
* 类中只有一个实例
* 在外界不能随意构建该类的实例
* 对外界提供方法,来访问该类的唯一实例
* 单例模式分为懒汉和饿汉式单例
* */
/***
* 懒汉式单例模式 优点:节省内存,需要这个单例对象才会创建(懒加载)延迟加载 缺点:每次都要判断对象是否为null,浪费时间,线程不安全 解决: 双重检查锁
**/
class Singleton {
/**
* 构造方法私有化
*/
private Singleton() {
System.out.println("构造方法");
}
/** 定义本类的实例 */
private static Singleton instance;
/**
* 对外界提供方法,来访问该类的唯一实例 线程安全问题:可以给方法加锁,但是锁的范围太大,降低效率 双重检查锁(double checked)
*/
public static synchronized Singleton getInstance() {
// 第一批来到线程都是null,进入if中在同步代码处等待,依次进入判断,第二批来的线程判断对象不是null,
// 就不需要,进入if中在进行等待了,节省了等待时间
**理解:** *if (instance == null) {
// 进入的线程再判断,对象就不是null,可以直接返回
synchronized (Singleton.class) {
// 如果多个线程同时过来,判断对象为Null,那么多线程都会进入if代码块中创建各自的对象
// 多线程过来后会在此处等待,轮流获得锁,进入同步代码块中判断对象为null,为null则创建对象出来,创建完后释放锁,后续获得锁
if (instance == null) {
System.out.println("创建对象");
instance = new Singleton();
}
}
}
return instance;
}
}*
/***
* 饿汉式单例模式 优点:每次判断对象是否为null,节省时间 线程安全
* 缺点:类加载时自动创建对象,无论用不用这个对象都会创建,浪费一定的内存空间,有可能浪费内存空间,立即加载,earlyLoading 解决: 加静态内部类
**/
class Singe {
/**
* 构造方法私有化
*/
private Singe() {
System.out.println("创建对象");
}
public static void m() {
System.out.println("mmm");
}
private static class SingleHolder {
/** 定义本类的实例 */
private static Singe instance = new Singe();
}
/** 对外界提供方法,来访问该类的唯一实例 */
public static Singe getInstance() {
return SingleHolder.instance;
}
}
/** 获取懒汉式单例对象的任务 **/
class GetInstanceTask implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
Singleton instance = Singleton.getInstance();
System.out.println(instance);
}
}
}
/** 枚举:类中只有特定的几个对象 */
enum Week {
ONE("星期一",1), TWO("星期二",2);
private String name;
private int num;
private Week(String name,int num) {
this.num=num;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
public class Treaddemo07 {
public static void main(String[] args) {
// 获取懒汉式单例对象
// 启动四个线程去获取懒汉式单例对象
// Thread t1 = new Thread(new GetInstanceTask());
// Thread t2 = new Thread(new GetInstanceTask());
// Thread t3 = new Thread(new GetInstanceTask());
// Thread t4 = new Thread(new GetInstanceTask());
//
// t1.start();
// t2.start();
// t3.start();
// t4.start();
Singe.m();
Week instance = Week.ONE;
System.out.println(instance);
System.out.println(instance.getName());
System.out.println(instance.getNum());
Week[]weeks=Week.values();
for(int i=0;i<weeks.length;i++) {
Week w=weeks[i];
System.out.println(w);
System.out.println(w.getName());
System.out.println(w.getNum());
}
}
}
JAVA面试题(理解单例模式中标志理解那一段源码)
最新推荐文章于 2024-05-12 20:46:47 发布