guguoyi / shareber

7 stars 0 forks source link

2018-12-07[Yolanda Yan] Singleton #5

Open yolandayan129 opened 5 years ago

yolandayan129 commented 5 years ago

MySingleton:

package com.yolanda.local;

import java.io.ObjectStreamException;
import java.io.Serializable;

public class MySingleton implements Serializable {

    private MySingleton() {
        // 避免反射
        if (instance != null) {
            throw new RuntimeException("The instance already created, can't be created twice");
        }
    }

    // 饿汉模式
    /*private static MySingleton instance = new MySingleton();

    public static MySingleton getInstance() {

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return instance;
    }*/

    // 懒汉模式
    /*private static MySingleton instance = null;

    public static MySingleton getInstance() {
        if(instance == null) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            instance = new MySingleton();
        }

        return instance;
    }*/

    // 静态内部类模式
    private static MySingleton instance;

    public static MySingleton getInstance() {
        return instance =  SingletonBuilder.instance;
    }

    private static class SingletonBuilder {
        private static MySingleton instance = new MySingleton();
    }

    private Object readResolve() throws ObjectStreamException {
        return instance;
    }
}

Test:

package com.yolanda.local;

import java.io.*;
import java.lang.reflect.Constructor;

public class TestSingleton {

    public static void main(String[] args) {
        testMultipleThread();
        testReflect();
        testSerializable();
    }

    // test multiple thread
    public static void testMultipleThread() {
        System.out.println("--------------------- Test testMultipleThread ------------------");
        TestSingletonWithMultipleThread[] multipleThread = new TestSingletonWithMultipleThread[10];

        for (int i = 0; i < multipleThread.length; i++) {
            multipleThread[i] = new TestSingletonWithMultipleThread();
        }

        for (int i = 0; i < multipleThread.length; i++) {
            multipleThread[i].start();
        }
    }

    public static void testReflect() {

        try {
            MySingleton s1 = MySingleton.getInstance();
            System.out.println("Test testReflect s1: " + s1.hashCode());

            Constructor<MySingleton> constructor = MySingleton.class.getDeclaredConstructor();
            constructor.setAccessible(true);
            MySingleton s2 = constructor.newInstance();

            System.out.println("Test testReflect s2: " + s2.hashCode());
        } catch (Exception e) {
            System.out.println("Test testReflect enter exception");
        }
    }

    public static void testSerializable() {

        try {
            // write
            MySingleton s1 = MySingleton.getInstance();
            ObjectOutputStream ops = new ObjectOutputStream(new FileOutputStream("E:\\workspaceYolanda\\test-file-folder\\test-serializable.txt"));
            ops.writeObject(s1);
            ops.flush();
            ops.close();

            // read
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\workspaceYolanda\\test-file-folder\\test-serializable.txt"));
            MySingleton s2 = (MySingleton)ois.readObject();

            System.out.println("Test testSerializable s1: " + s1.hashCode());
            System.out.println("Test testSerializable s2: " + s2.hashCode());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

TestSingletonWithMultipleThread:

package com.yolanda.local;

public class TestSingletonWithMultipleThread extends Thread {

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