java单例模式,多线程下实现

单例模式

必备条件:

1:private的构造方法。

2:private static 对象保存该类实例。

3:static方法返回该类实例。

(一)饿汉模式

/**
 * 单例模式
 * 1:线程安全实现
 * 2:浪费内存
 * @author 祥少
 *
 */
public class SingletonTest {

  //final关键字,导致一旦被初始化,一直占用该段内存(即使你不使用)
    public static final SingletonTest singletonTest = new SingletonTest();;

private SingletonTest() {

}

public static SingletonTest getSingleton() {

return singletonTest;
    }

public static void main(String[] args) {
        long current=System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(SingletonTest.getSingleton().hashCode());
                }
            }).start();
        }
        if (Thread.activeCount() > 1) {
            Thread.yield();
        }
        System.out.println("执行结束耗时:"+(System.currentTimeMillis()-current));
    }
}

(二)饱汉模式
/**
 * 单例模式
 * 1:线程不安全
 * getSingleton()函数线程不安全
 *@author 祥少
 */
public class SingletonTest {
    public static SingletonTest singletonTest = null;

private SingletonTest() {

}

public static SingletonTest getSingleton() {
        if (singletonTest == null) {
            singletonTest = new SingletonTest();
        }
        return singletonTest;
    }

public static void main(String[] args) {
        long current = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(SingletonTest.getSingleton().hashCode());
                }
            }).start();
        }

// 判断线程是否结束
        if (Thread.activeCount() > 1) {
            Thread.yield();
        }
        System.out.println("执行结束耗时:" + (System.currentTimeMillis() - current));
    }
}

线程安全改进方法:

(方法1)

public static synchronized SingletonTest getSingleton() {
        if (singletonTest == null) {
            singletonTest = new SingletonTest();
        }
        return singletonTest;
    }

优点:synchronized关键字实现线程安全。
缺点:整个函数加锁效率略低(几乎等于单线程)。

(方法2:双加锁)   

public static volatile SingletonTest singletonTest = null;

public static SingletonTest getSingleton() {
        if (singletonTest == null) {
            synchronized (SingletonTest.class) {
                if (singletonTest == null) {
                    singletonTest = new SingletonTest();
                }
            }            
        }
        return singletonTest;
    }

最佳实现:效率高,线程安全,volatile 保证操作原子性,只有%1的线程需要进入锁代码。

时间: 2024-08-04 02:30:37

java单例模式,多线程下实现的相关文章

普通int值在多线程下的递增操作

Java针对多线程下的数值安全计数器设计了一些类,这些类叫做原子类,其中一部分如下:  java.util.concurrent.atomic.AtomicBoolean;  java.util.concurrent.atomic.AtomicInteger;  java.util.concurrent.atomic.AtomicLong;  java.util.concurrent.atomic.AtomicReference;  下面是一个对比 AtomicInteger 与 普通 int

java工程优化——多线程下的单例模式

在最初学习设计模式时,我为绝佳的设计思想激动不已,在以后的工程中,多次融合设计模式,而在当下的设计中,我们已经觉察出了当初设计模式的高瞻远瞩,但是也有一些不足,需要我们去改进,有人说过,世界上没有绝对的事,当然,再简单的事情,环境变了,也会发生变化,今天和大家一起分享在多线程下单例模式的优化. 1,传统 首先,我们回顾下传统的单例(懒汉式)是如何工作的: public class SingletonClass{ private static SingletonClass instance=nul

单例模式在多线程下的多种实现模式

单例模式是23种设计模式中比较常见的设计模式,又因为其代码量精简,所以经常会被用在在面试中测试面试者的能力. 初级的单例模式很简单 实现两个要求 1构造方法私有化 2对外提供静态的,公开的获取对象的方法 所以:初级单例模式如下 public class Singelton {private Singelton(){} private static Singelton sin=null;public static Singelton getSingelton(){           if(sin

多线程下的单例模式

参加一个面试,被问到多线程下的单例模式会创建几个对象,总结一下: 首先我的单例是这么写的(懒汉式) public class Singleton{ private static Singleton singleton; private Singleton(){} public Singleton getInstance(){ if(singleton == null){ singleton = new singleton(); } return singleton; } } 这样写的话, 当线程

java多线程下如何调用一个共同的内存单元(调用同一个对象)

1 /* 2 * 关于线程下共享相同的内存单元(包括代码与数据) 3 * ,并利用这些共享单元来实现数据交换,实时通信与必要的同步操作. 4 * 对于Thread(Runnable target)构造方法创建的线程,轮到它来享用CPU资源时. 5 * 目标对象就会自动调用接口中的run()方法 6 * */ 7 8 /* ----------------举例子------------------- */ 9 10 /* 11 * 使用Thread类创建两个模拟猫和狗的线程,猫和狗共享房屋中的一桶

Java多线程20:多线程下的其他组件之CountDownLatch、Semaphore、Exchanger

前言 在多线程环境下,JDK给开发者提供了许多的组件供用户使用(主要在java.util.concurrent下),使得用户不需要再去关心在具体场景下要如何写出同时兼顾线程安全性与高效率的代码.之前讲过的线程池.BlockingQueue都是在java.util.concurrent下的组件,Timer虽然不在java.util.concurrent下,但也算是.后两篇文章将以例子的形式简单讲解一些多线程下其他组件的使用,不需要多深刻的理解,知道每个组件大致什么作用就行. 本文主要讲解的是Cou

java多线程下的所的概念

锁和synchronized关键字     为了同步多线程,Java语言使用监视器(monitors),一种高级的机制来限定某一 时刻只有一个线程执行一段受监视器保护的代码.监视器的行为是通过锁来实现的,每一个对象都有一个锁.    每个线程都有一个工作内存,在里面存放从所有线程共享的主内存里拷贝来的变量.为了访问一个共享的变量,一个线程通常先要获得一个锁并刷新它的工作内存,这将共享的值从主内存被拷贝到工作内存.当线程解锁时将会把工作内存里的值写回主内存.&n bsp;   一个线程能多次获得对

Java - 单例模式与多线程

单例模式大家并不陌生,分为饿汉式和懒汉式等. 线程安全的饿汉式单例 饿汉式单例在类第一次加载的时候就完成了初始化,上代码: public class MyObject { private static MyObject myObject = new MyObject(); public static MyObject getInstance(){ return myObject; } } 下面来验证饿汉式单例的线程安全性: public class MyThread extends Thread

【JAVA】HashMap的原理及多线程下死循环的原因

再次翻到以前工作中遇到的一个问题,HashMap在多线程下会出现死循环的问题,以前只是知道会死循环,导致CPU100%把机器拖跨,今天来彻底看看 首先来看下,HashMap的原理:HashMap是一个数组,对key使用hash算法计算出数组对应的下标i,然后把<key, value>插到table[i],如果两个不同的key被算在同一个i,那就出现冲突,又叫碰撞,这样就会在table[i]上形成一个链表:总结下来HashMap是一个数组+链表组成的数据结构: 我们知道,在往HashMap里pu

Java多线程21:多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask

CyclicBarrier 接着讲多线程下的其他组件,第一个要讲的就是CyclicBarrier.CyclicBarrier从字面理解是指循环屏障,它可以协同多个线程,让多个线程在这个屏障前等待,直到所有线程都达到了这个屏障时,再一起继续执行后面的动作.看一下CyclicBarrier的使用实例: public static class CyclicBarrierThread extends Thread { private CyclicBarrier cb; private int sleep