写法1:饿汉式
定义: 类加载到内存后,只实例化一个实例,JVM保证线程安全
优点:简单实用
缺点:不管是否会被使用,类装载时就完成实例化
public class Singleton1{
private static final Singleton1 INSTANCE = new Singleton1 ();
private Singleton1 (){
}
public static Singleton1 getInstance(){
return INSTANCE;
}
public void printStr(){
System.out.println("test");
}
}
/*
*测试类
*/
public class Test{
public static void main(String[]args){
Singleton1 singleton1 = Singleton1.getInstance();
singleton1.printStr();
}
}
写法2:饿汉式
定义: 类加载到内存后,只实例化一个实例,JVM保证线程安全
优点:简单实用
缺点:不管是否会被使用,类装载时就完成实例化
public class Singleton1{
private static Singleton1 INSTANCE ;
static{
INSTANCE = new Singleton1 ();
}
private Singleton1 (){
}
public static Singleton1 getInstance(){
return INSTANCE;
}
public void printStr(){
System.out.println("test");
}
}
/*
*测试类
*/
public class Test{
public static void main(String[]args){
Singleton1 singleton1 = Singleton1.getInstance();
singleton1.printStr();
}
}
写法3:懒汉式
优点:使用时再创建对象
缺点:多线程访问会有线程安全问题,多线程并发是会创建多个对象
public class Singleton1{
private static Singleton1 INSTANCE ;
private Singleton1 (){
}
public static Singleton1 getInstance(){
if(INSTANCE ==null){
INSTANCE = new Singleton1 ();
}
return INSTANCE;
}
public void printStr(){
System.out.println("test");
}
}
/*
*测试类
*/
public class Test{
public static void main(String[]args){
Singleton1 singleton1 = Singleton1.getInstance();
singleton1.printStr();
}
}
写法4:懒汉式
优点:加锁解决写法三的线程不安全问题
缺点:synchronized 效率降低
public class Singleton1{
private static Singleton1 INSTANCE ;
private Singleton1 (){
}
public static synchronized Singleton1 getInstance(){
if(INSTANCE ==null){
INSTANCE = new Singleton1 ();
}
return INSTANCE;
}
public void printStr(){
System.out.println("test");
}
}
/*
*测试类
*/
public class Test{
public static void main(String[]args){
Singleton1 singleton1 = Singleton1.getInstance();
singleton1.printStr();
}
}
写法5:懒汉式
优点:解决效率低的问题
缺点:存在线程不安全的问题
public class Singleton1{
private static Singleton1 INSTANCE ;
private Singleton1 (){
}
public static Singleton1 getInstance(){
if(INSTANCE ==null){
synchronized(Singleton1.class){
INSTANCE = new Singleton1 ();
}
}
return INSTANCE;
}
public void printStr(){
System.out.println("test");
}
}
/*
*测试类
*/
public class Test{
public static void main(String[]args){
Singleton1 singleton1 = Singleton1.getInstance();
singleton1.printStr();
}
}
写法6:懒汉式,双重检查
优点:解决线程不安全的问题
缺点:效率降低
public class Singleton1{
private static volatile Singleton1 INSTANCE ;
private Singleton1 (){
}
public static Singleton1 getInstance(){
if(INSTANCE ==null){
synchronized(Singleton1.class){
if(INSTANCE ==null){
INSTANCE = new Singleton1 ();
}
}
}
return INSTANCE;
}
public void printStr(){
System.out.println("test");
}
}
/*
*测试类
*/
public class Test{
public static void main(String[]args){
Singleton1 singleton1 = Singleton1.getInstance();
singleton1.printStr();
}
}
写法7:懒汉式,内部类写法
优点:解决线程不安全的问题、不用通过使用锁实现
缺点:
public class Singleton1{
private Singleton1 (){
}
//内部类
public static class Singleton1Holder{
private final static Singleton1 INSTANCE= new Singleton1 ();
}
public static Singleton1 getInstance(){
return Singleton1Holder.INSTANCE;
}
}
public void printStr(){
System.out.println("test");
}
}
/*
*测试类
*/
public class Test{
public static void main(String[]args){
Singleton1 singleton1 = Singleton1.getInstance();
singleton1.printStr();
}
}
写法8:枚举单例
优点:无线程安全问题、可以防止反序列化(因为枚举类没有构造方法)
public enum Singleton{
INSTANCE;
public void printStr(){
System.out.println("test");
}
public class Test{
public static void main(String[]args){
Singleton1 singleton1 = Singleton1.INSTANCE;
singleton1.printStr();
}
}
总结:
恶汉式:先创建对象
懒汉式:先判断再创建对象
语法最完美:写法8
最实用:方法1
根据实际场景采用对应方法
常见使用场景:
项目数据源、日志文件、系统的公共配置文件等。