类加载不只是Singleton.getInstance(),如果Singleton.add()(即:只使用该类的其他方法,而不使用该类对象)也会类加载
1、饿汉式
线程安全:类加载时,完成了创建
若没有使用过该对象,会造成内存浪费
public class Singleton1 {
//1、构造器必须私有化,防止new
private Singleton1(){}
//2、创建唯一对象
private static Singleton1 instance;//加不加final取决于是否需要释放资源(即让instance=null),需要的话就不加-----爱加不加,无所谓
static {
instance=new Singleton1();
}
//3、静态方法返回该对象(因为不能new,new的话就不是单例了,所以得使用static)
public static Singleton1 getInstance(){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return instance;
}
}
//饿汉式线程安全
public class Demo1 {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Singleton1.getInstance());//执行Singleton1.getInstance(),会先加载类,也就是会先执行static
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Singleton1.getInstance());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Singleton1.getInstance());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Singleton1.getInstance());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Singleton1.getInstance());
}
}).start();
}
}
2、懒汉式(不要使用,因为线程不安全)
懒加载:用的时候才加载
线程不安全
public class Singleton2 {
//1、构造器私有化
private Singleton2(){}
//2、创建单例对象
private static Singleton2 instance; //为什么不用final:因为static final要求必须写值,如果在这里写null,之后不能修改
//3、实例
public static Singleton2 getInstance(){
if(instance==null){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
instance=new Singleton2();
}
return instance;
}
}
public class Demo2 {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Singleton2.getInstance());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Singleton2.getInstance());
}
}).start();
}
}
3、静态内部类:
懒加载+线程安全(原理:外部类被类加载时,静态内部类不会被加载)
调用Singleton3.getInstance()时,将外部类加载,然后执行到Singleton.instance,才会加载内部类
public class Singleton3 {
//1、构造器私有化
private Singleton3(){}
//2、实例对象
private static class Singleton{
public static Singleton3 instance=new Singleton3();
}
//3、返回
public static Singleton3 getInstance(){
return Singleton.instance;
}
}