读书笔记——《Java多线程编程核心技术》第六章

第六章主要讲了单例模式与多线程的关系。下面我主要总结一下单例模式的几种方式。

  1. 饿汉模式(简单就不说了)
  2. 懒汉模式(在多线程环境中,用DCL–double check lock来实现)
  3. 静态内部类

    public class MyObject4 {

    private static class MyObjectHandler{
    
        private static MyObject4 object = new MyObject4();
    }
    
    private MyObject4(){}
    
    public static MyObject4 getInstance(){
    
        return MyObjectHandler.object;
    }
    

    }

    在线程中,我们打印对象的hashcode
    public class MyThread4 extends Thread {

    @Override
    public void run(){
    
        System.out.println(MyObject4.getInstance().hashCode());
    }
    

    }

    最后在主线程中,启动三个线程去打印该对象的hashCode。

    public class Run5 {

    public static void main(String[] args) {
    
        MyThread4 t1 = new MyThread4();
        MyThread4 t2 = new MyThread4();
        MyThread4 t3 = new MyThread4();
        t1.start();
        t2.start();
        t3.start();
    }
    

    }

    结果三个值相同,证明实现了单例模式。

  4. 序列化与反序列化的单例模式实现

    public class MyObject5 implements Serializable {

    private static final long serialVersionUID = 888L;
    
    private static class MyObjectHandler {
    
        private static final MyObject5 myObject = new MyObject5();
    
    }
    
    private MyObject5() {
    }
    
    public static MyObject5 getInstance() {
    
        return MyObjectHandler.myObject;
    }
    
    //protected Object readResolve() throws //ObjectStreamException {

    //    System.out.println("调用了readResolve方法!");
    //    return MyObjectHandler.myObject;
    //}

}

在Main中执行如下代码:

public class SaveAndRead {

    public static void main(String[] args) {

        try {
            MyObject5 myObject = MyObject5.getInstance();
            FileOutputStream fosRef = new FileOutputStream(new File(
                    "myObjectFile.txt"));
            ObjectOutputStream oosRef = new ObjectOutputStream(fosRef);
            oosRef.writeObject(myObject);
            oosRef.close();
            fosRef.close();
            System.out.println(myObject.hashCode());
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            FileInputStream fisRef = new FileInputStream(new File(
                    "myObjectFile.txt"));
            ObjectInputStream iosRef = new ObjectInputStream(fisRef);
            MyObject5 myObject = (MyObject5) iosRef.readObject();
            iosRef.close();
            fisRef.close();
            System.out.println(myObject.hashCode());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

就会发现其hashCode不同,那么如何解决呢?我们只需要取消上面注释的代码就可以。
  1. 静态代码块

      static{
        object = new Object();
    }
    
  2. 使用enum类型