线程安全问题-单例设计模式

第一种:饿汉式单例设计模式

在类加载的时候就创建好了一个静态的对象供系统使用,以后不再改变,所以天生就是线程安全的。

但是初始化就占用了系统的资源。

package thread;

/*
 * 饿汉式单例模式:饿汉式在类一创建的时候就已经创建好了一个静态的对象供系统使用,以后不再改变,所以天生就是线程安全的
 */

class Singleton3{
    private Singleton3(){

    }

    private static final Singleton3 INSTANCE = new Singleton3();

    public static Singleton3 getInstance(){

        return INSTANCE;

    }
}

//这里为了测试多线程并发调用单例对象,所以使用了多线程,即创建线程任务对象
class Demo3 implements Runnable{

    @Override
    public void run() {
        Singleton3 instance = Singleton3.getInstance();
        System.out.println(Thread.currentThread().getName()+"..."+instance);
    }

}
public class ThreadDemo3{

    public static void main(String[] args) {
        //创建线程任务对象
        Demo3 d3 = new Demo3();
        //创建三个线程对象
        Thread t1 = new Thread(d3);
        Thread t2 = new Thread(d3);
        Thread t3 = new Thread(d3);
        //开启线程
        t1.start();
        t2.start();
        t3.start();
    }

}

运行结果:

第二种:懒汉式单例设计模式

懒汉式本身是不可以实现单例模式的,这里是通过同步代码块来实现的。

只有在第一次调用获取对象方法的时候才去初始化这个单例对象。

package thread;
/*
 * 懒汉式本身是不可以实现单例模式的,这里是通过判断和同步代码块完成的
 * 懒汉式单例模式:只有在第一次调用getInstance的时候初始化这个单例
 */
class Singleton4{
    private Singleton4(){}
    private static Singleton4 instance = null;
    public static Singleton4 getInstance() throws InterruptedException{
        /*
         * 这里为了方便测试多线程并发的情况更加准确
         * 让所有调用该线程的方法谁20毫秒,这样cpu的时间片可以充分的让其他线程也走到这一步
         */
        Thread.sleep(20);
        if (instance == null) {
            /*
             * 让所有的线程走过上面代码的线程,在进入同步代码块前,都睡20毫秒
             * 这样会有多个线程准备进入同步代码块
             */
            Thread.sleep(20);
            synchronized (Singleton4.class) {
                //让进入当前同步代码块的代码睡20毫秒,当然此时其他线程肯定是在外面等着的
                Thread.sleep(20);
                if (instance == null) {//加这一层的判断,是为了让其他准备进入的同步代码块知道,如果已经有一个线程实话了对象,他们就不用再次实话对象了
                    instance = new Singleton4();
                }
            }
        }
        return instance;

    }

}

class Demo2 implements Runnable{

    @Override
    public void run() {
        Singleton4 instance = null;
        try {
            instance = Singleton4.getInstance();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"..."+instance);

    }

}

public class ThreadDemo4{
    public static void main(String[] args) {
        //创建实现了Runable接口的线程任务对象
        Demo2 d = new Demo2();
        //创建三个并发线程进行测试
        Thread t1 = new Thread(d);
        Thread t2 = new Thread(d);
        Thread t3 = new Thread(d);
        //开启线程,让cpu时间片切调用run方法
        t1.start();
        t2.start();
        t3.start();
    }

}

运行结果:

第三种方式:静态内部类

为什么可以实现单例模式:静态内部类只会在第一调用的时候被加载一次,所以是线程安全的

package thread;

class Singleton5{

    private Singleton5(){}
    private static class lazyHoler{
        private static final Singleton5 INSTANCE = new Singleton5();
    }

    public static Singleton5 getInstance(){
        return lazyHoler.INSTANCE;
    }
}

//线程任务类
class Demo5 implements Runnable{

    @Override
    public void run() {
        Singleton5 instance = Singleton5.getInstance();
        System.out.println(Thread.currentThread().getName()+"..."+instance);

    }

}
public class ThreadDemo5 {
    public static void main(String[] args) {

        //创建线程任务对象
        Demo5 d5 = new Demo5();
        Thread t1 = new Thread(d5);
        Thread t2 = new Thread(d5);
        Thread t3 = new Thread(d5);
        //开启线程
        t1.start();
        t2.start();
        t3.start();

    }

}

运行结果:

时间: 2024-08-19 19:25:53

线程安全问题-单例设计模式的相关文章

Java设计模式之一 单例设计模式

1.什么叫设计模式: 设计模式的概念首先来源于其它行业:建筑业,在早起建房子的时候,肯定是经验缺乏.显得杂乱无序的,这就会造成很多问题,在行业发展过程,通过不断的经验积累,前辈们针对这些问题提出了合理解决方案,这就是设计模式,参照设计模式往往可以解决很多问题,在计算机编程方面,也会出现类似问题,所以牛人们把这些解决问题的方案进行归类和总结,形成了面向对象编程的23种设计模式. 2.单例模式(特点): Java中单例模式定义:"一个类有且仅有一个实例,并且自行实例化向整个系统提供."通过

黑马程序员——多线程下的单例设计模式的安全问题

//多线程下的单例设计模式 class Sing { //饿汉式不存在安全问题,因为其不是线程同步的 private static Sing s = new Sing(); private Sing(){} public static Sing getInstance() { return s; } } class Single { private static Single s = null; private Single(){} public static Single getInstanc

单例设计模式-(你确定自己写的懒汉单例真的是线程安全的吗)

1.单例设计模式的优缺点 优点: 1):只创建一个实例,就可以到处使用,加快创建实体的效率 缺点: 1):如果使用的频率比较低,实例会一直占据着内存空间,会造成资源浪费 2):可能会出现线程安全问题 2.单例设计模式的两种定法(饿汉.懒汉) 饿汉方法写法:(可能会造成资源浪费,类一被加载就创建了实例,但并不能确保这个实例什么时候会被用上) package com.zluo.pattern; /** * * 项目名称:single-instance <br> * 类名称:SingleInstan

JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制

JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是class对象 我们在上节验证了同步函数的锁是this,但是对于静态同步函数,你又知道多少呢? 我们做一个这样的小实验,我们给show方法加上static关键字去修饰 private static synchronized void show() { if (tick > 0) { try { Thread

线程安全的懒汉式单例设计模式

首先回顾一下单利设计模式: 单利设计模式是通过某种方式使某个类只能创建一个对象实例供外界使用. 单利设计模式分为懒汉式和饿汉式: 饿汉式是线程安全的: 1 //饿汉式单利设计模式: 2 class Single{ 3 private static final Single single = new Single(); 4 private Single(){} 5 public static Single getInstance(){ 6 return s; 7 } 8 } 饿汉式实现线程安全,可

【黑马】程序员————多线程(二)单例设计模式、线程间通信,JDK1.5互斥锁

------Java培训.Android培训.iOS培训..Net培训.期待与您交流!----- 一.单例设计模式 单例设计模式的意义: A.保证类在内存中只有一个对象,不提供外部访问方式,构造函数用private修饰. B.提供公共方法(static修饰,类的静态方法),获取类的实例.单例设计模式分为饿汉和懒汉两种模式. 饿汉式&懒汉式 class Test33 { public static void main(String[] args) { Fanjianan.getInstance()

【学习笔记】单例设计模式笔记

单例设计模式是常见的设计模式之一.通过单例实现所需求类在系统中只存在唯一一个实例. 单例设计模式分两种:懒汉单例设计模式和饿汉单例设计模式,两者设计思路一致,实现有微小不同. 实现代码: 1 public class HungryMan { 2 3 private HungryMan(){};//私有的构造方法保证HungryMan类无法在外部使用构造方法实例化 4 private static final HungryMan hungryMan=new HungryMan();//在类内定义一

JAVA_SE基础——37.单例设计模式

本文继续介绍23种设计模式系列之单例模式. 我们在javaSE的基础学习中,会讲到:单例设计模式.模板设计模式.装饰者设计模式.观察者设计模式.工厂设计模式 我以后随着水平的提高,我会专门开个分类写设计模式的.现在请原谅我的知识面有限-- 设计模式→中的    "模式" 二字是什么意思.. 模式:模式就是解决 一类 问题的固定步骤 . 模式的概念最早起源于建筑行业.... 建房子的步骤都是一样子: 打地基-----> 浇柱子------->盖楼面--------->砌

黑马程序员--Java基础学习笔记【单例设计模式、网络编程、反射】

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 设计模式分类: 创建模式:是对类的实例化过程的抽象化,又分为类创建模式和对象创建模式 类创建模式:工厂方法模式 对象-:简单工厂(静态工厂方法)模式.抽象工厂模式.单例模式.建造模式- 结构模式:描述如何将类或者对象结合在一起形成更大的结构 适配器模式.缺省模式.合成模式.装饰模式(包装模式).门面模式- 行为模式:对不同的对象之间划分责任和算法的抽象化 不变模式.策略模式.迭代子模式.命令模