1.代碼示例
public class Singleton
{
private Singleton(){}
static {
System.out.println("This's static code block!");
}
private static class SingletonHandler {
private static Singleton singleton = new Singleton();
static {
System.out.println("This's innerClass's static code block");
}
}
public static Singleton getInstance(){
return SingletonHandler.singleton;
}
public static void display(){
System.out.println("This's display!");
}
}
public class SingletonTest
{
private SingletonTest(){}
static class MyThread extends Thread {
@Override
public void run()
{
super.run();
System.out.println("Thread running_"+Singleton.getInstance());
}
}
public static void main(String[] args)
{
MyThread th1 = new MyThread();
MyThread th2 = new MyThread();
MyThread th3 = new MyThread();
/*@1
th1.start();
th2.start();
th3.start();
*/
/*@2
Singleton.display();
*/
}
}
2. 運行結果及解釋
情況一(注釋 @1代碼,注釋 @2的代碼)
//運行結果 為空
解釋:外部類和內部類都沒有加載
情況二(執行 @1代碼)
//運行結果
This's static code block!
This's innerClass's static code block
Thread running_com.singleton.Singleton@4f19c297
Thread running_com.singleton.Singleton@4f19c297
Thread running_com.singleton.Singleton@4f19c297
解釋: 外部類Singleton和內部類SingletonHandler都加載了,因為他們的靜態代碼塊加載了
情況三(注釋 @1代碼,執行 @2的代碼)
//運行結果
This's static code block!
This's display!
解釋:外部類加載了,而內部類沒有加載,因為加載了類,就一定會執行靜態代碼塊
3. 結論
終上實驗:內部類SingletonHandler只有在getInstance()方法第一次調用的時候才會被加載(實現了延遲加載效果),而且其加載過程是線程安全的(實現線程安全)。內部類加載的時候只實例化了一次instance