java 单例模式 及其线程不安全性演示

2 篇文章 0 订阅
1 篇文章 0 订阅
  1. 恶汉模式Entity
package com.myibs.test.service.singleObject;

/**
 *获取唯一可用的对象,恶汉式。来了照单全收,全部创建,浪费资源
 */
public class Singleton {

    public String getsStr() {
        return sStr;
    }

    public void setsStr(String sStr) {
        this.sStr = sStr;
    }

    /**
     * 记得哦,初始化时是 1, 事后通过代码来修改的
     */
    private String sStr="1";

    //创建 SingleObject 的一个对象
    private static Singleton instance = new Singleton();

    /**
     * 记让构造函数为 private,这样该类就无法通过外部被实例化
     */
    private Singleton(){
        System.out.println("SingleObject construction");
    }


    /**
     *获取唯一可用的对象,恶汉式
     */
    public static Singleton getInstance(){
        return instance;
    }

    public void showMessage(){
        System.out.println("Hello World! " + sStr);
    }

}

  1. 懒汉模式Entity: 主要采用了Synchronized锁确保了新建时等待调用同一对象。
package com.myibs.test.service.singleObject;

public class SingletonLazy {

    public String getsStr() {
        return sStr;
    }

    public void setsStr(String sStr) {
        this.sStr = sStr;
    }

    private String sStr="1";

    //创建 SingleObject 的一个对象
    private static SingletonLazy instance = new SingletonLazy();

    //让构造函数为 private,这样该类就无法通过外部被实例化
    private SingletonLazy(){}

    //使用Synchronized方式锁定,获取唯一可用的对象
    public static synchronized SingletonLazy getInstance(){
        if (instance == null) {
            instance = new SingletonLazy();
        }
        return instance;
    }

    public void showMessage(){
        System.out.println("Hello World! " + sStr);
    }

}

  1. 恶汉模式Thread
package com.myibs.test.service.singleObject;

public class SingletonThread extends Thread {

    public String getName1() {
        return name1;
    }

    public void setName1(String name1) {
        this.name1 = name1;
    }

    String name1;

    //创建 SingleObject 的一个对象
    private static SingletonThread instance = new SingletonThread();

    //让构造函数为 private,这样该类就无法通过外部被实例化
    private SingletonThread(){}

    //获取唯一可用的对象
    public static SingletonThread getInstance(){
        return instance;
    }

    public void showMessage(){
        System.out.println("Hello World!: " + name1 );
    }

    @Override
    public void run() {
        try {
            Thread.sleep(100);
            for (int i = 0; i < 10; i++) {
                System.out.println(name1 + ": 运行,i = " + i);
            }
        } catch (InterruptedException e) {
            System.out.println(name1 +" Thread is terminated.....");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

  1. Demo主程序
package com.myibs.test.service.singleObject;

import java.util.Objects;

public class SingletonPatternDemo {

    public static void main(String[] args) {

        //Test 1: 不合法的构造函数
        //编译时错误:构造函数 SingleObject() 是private/不可见的
        //SingleObject object = new SingleObject();

        //Test 2:单例模式(Lazy)
        //此项是基础测试
        Singleton object2 = Singleton.getInstance();
        //显示消息
        object2.showMessage();
        object2.setsStr("2");
        object2.showMessage();

        Singleton object21 = Singleton.getInstance();
        object21.setsStr("3");  //由于大家共享一个变量,这个就是要命的地方了
        object2.showMessage();
        object21.showMessage();
        if (object2 == object21) {
            System.out.println("These two objects are the same");
        }
        if (object2.equals(object21)) {
            System.out.println("These two objects are the same");
        }
        if (Objects.equals(object2,object21)) {
            System.out.println("These two objects are the same");
        }

        //Test 3:单例模式(Lazy)
        //此项是基础测试
        SingletonLazy object3 = SingletonLazy.getInstance();
        //显示消息
        object3.showMessage();
        object3.setsStr("2");
        object3.showMessage();

        //关键是这里,再去建立的时候就直接返回之前的单例了,返回值就是2
        SingletonLazy object1 = SingletonLazy.getInstance();
        object1.showMessage();
        object3.setsStr("3");
        object1.showMessage();   //由于大家共享一个变量,这个就是要命的地方了
        if (object1 == object3) {
            System.out.println("These two objects are the same");
        }
        if (object3.equals(object1)) {
            System.out.println("These two objects are the same");
        }
        if (Objects.equals(object1,object3)) {
            System.out.println("These two objects are the same");
        }

        //Test 4:看看是否能获取多个对象,结果是不可以
        SingletonThread objectThread1 = SingletonThread.getInstance();
        SingletonThread objectThread2 = SingletonThread.getInstance();
        SingletonThread objectThread3 = SingletonThread.getInstance();

        objectThread1.setName1("111");
        objectThread2.setName1("222");
        objectThread3.setName1("333");
        System.out.println(objectThread1 + "|" + objectThread1.hashCode() + "|" + System.identityHashCode(objectThread1));
        System.out.println(objectThread2 + "|" + objectThread2.hashCode() + "|" + System.identityHashCode(objectThread2));
        System.out.println(objectThread3 + "|" + objectThread3.hashCode() + "|" + System.identityHashCode(objectThread3));
        objectThread1.showMessage();
        objectThread2.showMessage();
        objectThread3.showMessage();

        try {
            objectThread1.start();  /** 代码在此处正常*/
            objectThread2.start();  /** Thread Exception,因为无法在此Object上继续new thread*/
            objectThread3.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值