//懒汉式单例
class Single{
private final static Single single = new Single();
private Single(){
}
public static Single getInstance(){
return single;
}
}
2.优化饿汉式
因为私有了构造器,导致无法使用new创建对象,就必须使用静态方法, Single single = new Single();这局会导致Single对象提前加载入内存中的,若此时Single中有大量空间申请的业务,会导致还未调用,就占满内存。则优化
//饿汉式单例
class Single{
private static Single single;
private Single(){
}
public static Single getInstance(){
if (single == null){
single = new Single();
}
return single;
}
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
public void run() {
Single i2 = Single.getInstance();
System.out.println(i2);
}
}).start();
}
}
则我们加入锁
class Single{
private static Single single;
private Single(){
}
public static Single getInstance(){
if (single == null){
synchronized (Single.class){
if (single == null){
single = new Single();
}
}
}
return single;
}
}
4.优化禁止指令重排
由于new Single()这句话不是原子性操作,可能出现指令重排的可能所以
class Single{
private volatile static Single single;
private Single(){
}
public static Single getInstance(){
if (single == null){
synchronized (Single.class){
if (single == null){
single = new Single();
}
}
}
return single;
}
}
5.优化无参构造器
由于有反射机制,仍然可以绕过私有构造器。
public class Test2 {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
public void run() {
try {
Constructor<?> declaredConstructor = Single.class.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
Single s1 = (Single) declaredConstructor.newInstance();
System.out.println(s1);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
}
我们拦截反射操作
class Single{
private volatile static Single single;
private static int flag = 0;
private Single() throws Exception {
synchronized (Single.class){
if (flag == 0){
flag = 1;
}else{
throw new Exception("请勿使用反射");
}
}
}
public static Single getInstance() throws Exception {
if (single == null){
synchronized (Single.class){
if (single == null){
single = new Single();
}
}
}
return single;
}
}
6.但反射仍然能给标志位改了。
public class Test2 {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
public void run() {
try {
Constructor<?> single = Single.class.getDeclaredConstructor();
single.setAccessible(true);
//给标志位改了。
Field flag = Single.class.getDeclaredField("flag");
flag.setAccessible(true);
flag.set(single,0);
Single s1 = (Single) single.newInstance();
System.out.println(s1);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
}
1.单例模式的核心就是私有构造器//懒汉式单例class Single{ private final static Single single = new Single(); private Single(){ } public static Single getInstance(){ return single; }}2.优化饿汉式因为私有了构造器,导致无法使用new创建对象,就必须使用静态方法,Single single = n.