设计模式 单例模式
- 饿汉式(经典的一种写法)
package 单例模式;
/*
* 饿汉式
* 类加载到内存后,就实例化一个单例,JVM保证线程安全
* 简单使用,推荐使用
*
* 最常见的
*
* 唯一缺点:不管用到与否,类加载时就完成实例化
* (不使用的话,加载就没有意义了)
* */
public class T1 {
private T1(){ }
private static T1 t1=new T1();
public static T1 getInstance(){
return t1;
}
public void m(){
System.out.println("mm");
}
public static void main(String[] args) {
T1 t1=T1.getInstance();
T1 t2=T1.getInstance();
System.out.println(t1.hashCode());
}
}
- 懒汉式
package 单例模式;
/*lazy loading
* 懒汉式
* 虽然达到了按需初始化的目的,**但是也带来了线程不安全的问题**
* */
public class T3 {
private T3(){}
private static T3 t3=null;
public static T3 getInstance(){
if(t3==null){
//为了测试线程
try{
Thread.sleep(10);
}catch(InterruptedException e){
e.printStackTrace();
}
t3=new T3();
}
return t3;
}
public void m(){
System.out.println("mm");
}
public static void main(String[] args) {
for (int i=0;i<100;i++){
new Thread(()->{
System.out.println(T3.getInstance().hashCode());
}).start();
}
}
}
- 对懒汉式进行改进
package 单例模式;
/*
* 通过加锁可以解决多线程安全问题
*
* synchronized
*
* 对懒汉式的改进,但会对效率降低
*
* */
public class T4 {
private T4(){}
private static T4 t4=null;
public static synchronized T4 getInstance(){
if(t4==null){
//为了测试线程
try{
Thread.sleep(10);
}catch(InterruptedException e){
e.printStackTrace();
}
t4=new T4();
}
return t4;
}
public void m(){
System.out.println("mm");
}
public static void main(String[] args) {
for (int i=0;i<100;i++){
new Thread(()->{
System.out.println(T4.getInstance().hashCode());
}).start();
}
}
}
package 单例模式;
/*
* 解决了效率低的问题
* 但是也解决不了反序列化
* */
public class T5 {
private T5(){}
private static volatile T5 t5=null;
public static T5 getInstance(){
if(t5==null){
synchronized (T5.class){
if (t5==null){
try{
Thread.sleep(10);
}catch(InterruptedException e){
e.printStackTrace();
}
t5=new T5();
}
}
}
return t5;
}
public void m(){
System.out.println("mm");
}
public static void main(String[] args) {
for (int i=0;i<100;i++){
new Thread(()->{
System.out.println(T4.getInstance().hashCode());
}).start();
}
}
}
- 静态内部类
package 单例模式;
/*
* 静态内部类
*
* JVM保证单例
*
* 加载外部类时不会加载内部类,这样可以实现懒加载
* 算完美的
* */
public class T6 {
private T6(){}
private static class T6Holder{
private final static T6 t6=new T6();
}
public static T6 getInstance(){
return T6Holder.t6;
}
public void m(){
System.out.println("mm");
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(()->{
System.out.println(T6.getInstance().hashCode());
}).start();
}
}
}
- 枚举类(写着很方便)
package 单例模式;
/*
* 不仅可以解决线程同步,还可以防止序列化(原因:没有构造方法)
* 通过写一个枚举类来实现
* 这是一位java语言创建者写的(可以参考一下这本书《Effective Java》)
* 这也是我听说的
* */
public enum TT {
tt;
public void m(){}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(()->{
System.out.println(TT.tt.hashCode());
}).start();
}
}
}
总结:
单例模式也是较为常用的一种设计模式,它的核心就是只有一个实例对象(要不然也不会叫单例模式了),使用中,要注意的就是私有构造方法,防止产生新的对象。它也可以有很多公有实例方法,来实现行为。
学习设计模式的过程中,一定要多敲代码,不然学得快,忘得也快。