比如一个团队多个开发者都需要操作日志文件,如果每个人都实例化一个日志对象,会导致不必要的开销。为了解决这类问题,单例模式产生了。单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点。Windows系统中的回收站就是典型的一种单例模式应用,多次打开回收站不会创建新的窗口。
package SingletonPattern;
public class Singleton01 {
private static final Singleton01 INSTANCE = new Singleton01();
private Singleton01(){};
public static Singleton01 getInstance(){return INSTANCE;}
public void method(){
System.out.println("Happy Everyday");
}
public static void main(String[] args) {
Singleton01 m1 = Singleton01.getInstance();
Singleton01 m2 = Singleton01.getInstance();
System.out.println(m1 == m2);
}
}
package SingletonPattern;
import org.omg.PortableServer.THREAD_POLICY_ID;
public class Singleton02 {
//不能定义为final型,因为常量需要初始化
private static Singleton02 INSTANCE;
private Singleton02(){
}
public static Singleton02 getInstance(){
if(INSTANCE == null){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
INSTANCE = new Singleton02();
}
return INSTANCE;
}
public void method(){
System.out.println("Happy Everyday");
}
public static void main(String[] args) {
for(int i = 0; i < 10; i++){
//同一类的不同对象hashcode是不同的
new Thread(()->{
System.out.println(Singleton02.getInstance().hashCode());
}).start();
}
}
}
1184893857
219573733
449584288
1924898670
103512977
585605895
967740059
1802506717
499531361
1416599099
当多线程操作时,懒汉模式会出现,线程不安全的问题,比如A,B两个线程同时首次创建单例对象,A线程进入判空条件,创建对象之前,B线程此时INSTANCE依然为空,此时A,B线程会创建两个对象。
package SingletonPattern;
import org.omg.PortableServer.THREAD_POLICY_ID;
public class Singleton03 {
//不能定义为final型,因为常量需要初始化
private static Singleton03 INSTANCE;
private Singleton03(){
}
public static synchronized Singleton03 getInstance(){
if(INSTANCE == null){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
INSTANCE = new Singleton03();
}
return INSTANCE;
}
public void method(){
System.out.println("Happy Everyday");
}
public static void main(String[] args) {
for(int i = 0; i < 10; i++){
new Thread(()->{
System.out.println(Singleton03.getInstance().hashCode());
}).start();
}
}
}
1416599099
1416599099
1416599099
1416599099
1416599099
1416599099
1416599099
1416599099
1416599099
1416599099
package SingletonPattern;
import org.omg.PortableServer.THREAD_POLICY_ID;
public class Singleton04 {
//不能定义为final型,因为常量需要初始化
private static volatile Singleton04 INSTANCE;
private Singleton04(){
}
public static synchronized Singleton04 getInstance(){
if(INSTANCE == null){
synchronized (Singleton04.class) {
if(INSTANCE == null) {
INSTANCE = new Singleton04();
}
}
}
return INSTANCE;
}
public void method(){
System.out.println("Happy Everyday");
}
public static void main(String[] args) {
for(int i = 0; i < 10; i++){
new Thread(()->{
System.out.println(Singleton04.getInstance().hashCode());
}).start();
}
}
}
package SingletonPattern;
import sun.applet.AppletResourceLoader;
/**
* 静态内部类方式
*/
public class Singleton05 {
private Singleton05(){};
private static class Singleton05Holder{
private final static Singleton05 INSTANCE = new Singleton05();
}
public static Singleton05 getInstance(){
return Singleton05Holder.INSTANCE;
}
public void method(){
System.out.println("Happy Everyday");
}
public static void main(String[] args) {
for(int i = 0; i < 10; i++){
new Thread(()->{
System.out.println(Singleton05.getInstance().hashCode());
}).start();
}
}
}
package SingletonPattern;
public enum Singleton06 {
INSTANCE;
public void method(){
System.out.println("Happy Everyday");
}
public static void main(String[] args) {
for(int i = 0; i < 10; i++){
new Thread(()->{
System.out.println(Singleton05.getInstance().hashCode());
}).start();
}
}
}
原文:https://www.cnblogs.com/happysml/p/13849959.html