注意:这里只是看书,做下笔记,只为让自己思路更清晰,外加上自己的一点见解或者测试
饿汉式
public class Singleton {
/**
* 先私有构造函数,避免直接构造
*/
private Singleton(){}
/***
* 饿汉式
*/
private static final Singleton singleton = new Singleton();
public Singleton getInstance(){
return singleton;
}
}
上面是饿汉式,由获取前对象已经创建,对象不会再轻易变化。只要对象不变化,那么多线程就不会出现问题,也就是说不会出现线程安全问题。
总结:
1.未获取已经创建,会浪费内存
2.使用简单,不存在线程安全问题
懒汉式
public class Singleton {
/**
* 先私有构造函数,避免直接构造
*/
private Singleton(){}
/***
* 懒汉式,有需要才创建对象
*/
private static volatile Singleton singleton = null;
public static synchronized Singleton getInstance(){
if(singleton== null){
System.out.println(“进行”);
singleton = new Singleton();
}
return singleton;
}
public String toString() {
return “Singleton=” + super.toString();
}
}
线程获取单例对象,用于测试并发
public class ThreadGetSingleton implements Runnable{
public void run() {
System.out.println(Thread.currentThread().getId() + ” — Singleton==”+Singleton.getInstance());
}
}
public class TestGetSington {
public static void main(String[] args) {
ThreadGetSingleton threadGetSingleton = new ThreadGetSingleton();
ThreadGetSingleton threadGetSingleton2 = new ThreadGetSingleton();
ThreadGetSingleton threadGetSingleton3 = new ThreadGetSingleton();
ThreadGetSingleton threadGetSingleton4 = new ThreadGetSingleton();
ThreadGetSingleton threadGetSingleton5 = new ThreadGetSingleton();
ThreadGetSingleton threadGetSingleton6 = new ThreadGetSingleton();
Thread thread1 = new Thread(threadGetSingleton);
Thread thread2 = new Thread(threadGetSingleton2);
Thread thread3 = new Thread(threadGetSingleton3);
Thread thread4 = new Thread(threadGetSingleton4);
Thread thread5 = new Thread(threadGetSingleton5);
Thread thread6 = new Thread(threadGetSingleton6);
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread5.start();
thread6.start();
}
}
运行结果:
懒汉式构建对象
懒汉式构建对象
懒汉式构建对象
15 — Singleton==Singleton=sington2.Singleton@36fd35c5
懒汉式构建对象
懒汉式构建对象
14 — Singleton==Singleton=sington2.Singleton@33918ac4
懒汉式构建对象
13 — Singleton==Singleton=sington2.Singleton@26484d1e
12 — Singleton==Singleton=sington2.Singleton@3661fa09
10 — Singleton==Singleton=sington2.Singleton@5c2a3f44
11 — Singleton==Singleton=sington2.Singleton@4968bb15
发现线程同时进去创建对象了,也就是说产生了线程并发的问题了。
上面是懒汉式,开始不会创建对象,防止内存消耗。按照需要创建,但是这样对象会变化。由于对象会产声变化,那么就会存在多线程并发问题,也就是我们常说的线程安全问题。
下面是加上同步锁的代码:
public class Singleton {
/**
* 先私有构造函数,避免直接构造
*/
private Singleton(){}
/***
* 懒汉式,有需要才创建对象
*/
private static volatile Singleton singleton = null;
public static synchronized Singleton getInstance(){
if(singleton== null){
System.out.println(“懒汉式构建对象”);
singleton = new Singleton();
}
return singleton;
}
public String toString() {
return “Singleton=” + super.toString();
}
}
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/264063.html