Java 多线程(四)—— 单例模式
这篇博客介绍线程安全的应用——单例模式。
单例模式
单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。
双重校验锁
实例:
/**
* @author: ChenHao
* 关于懒汉式的线程安全问题,使用同步机制
* 对于一般的方法内,使用同步方法块,可以考虑使用this
* 对于静态方法而言,使用当前类充当锁。
*/
public class TestSingleton {
public static void main(String[] args) {
System.out.println(MySingle.getInstance());
System.out.println(MySingle.getInstance());
}
} class MySingle{
//声明一个私有的静态变量,第一次调用才初始化,避免内存浪费。
private volatile static MySingle instance=null;
//让构造器为private私有化,避免外部直接创建对象
private MySingle(){}
public static MySingle getInstance(){
if(null ==instance){//提高效率:如果已经存在对象,则不进行锁等待,直接返回对象,只有当对象为空才会进入锁等待,这里可以在第一个进入锁创建对象后,sleep10秒来放大效果
//这里有五个线程等待
synchronized(MySingle.class){
//第一次:当一个线程进来后,其他线程都在锁外面
//第一个线程创建对象后,释放锁,其他线程得到锁后,如果instance不为null,则不需要创建
if(null ==instance){
instance =new MySingle();
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
return instance;
}
}
代码分析:多个线程同时创建MySingle类的实例,比如现在有6个线程,第一次同时调用getInstance()静态方法,
线程A获取了锁,其他5个线程都在synchronized(MySingle.class)外面等待,第一个线程创建对象后,释放锁,其他线程得到锁后,如果instance不为null,则不需要创建;
第一个if(null ==instance)作用是提高效率:如果已经存在对象,则不进行锁等待,直接返回对象,只有当对象为空才会进入锁等待,这里可以在第一个进入锁创建对象后,sleep10秒来放大效果,此时已经创建了instance ,但是还没有释放锁,所以新来的线程不需要再等待锁,直接使用已经创建好的instance;
第二个if(null ==instance)判断instance是否已经存在,如果第一个线程已经创建instance,并释放锁,接下来的线程进入后则不需要再创建;
运行结果:输出相同的对象实例
饿汉
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
CAS(AtomicReference)实现单例模式
public class Singleton {
private static final AtomicReference<Singleton> INSTANCE = new AtomicReference<Singleton>(); private Singleton() {} public static Singleton getInstance() {
for (;;) {
Singleton singleton = INSTANCE.get();
if (null != singleton) {
return singleton;
} singleton = new Singleton();
if (INSTANCE.compareAndSet(null, singleton)) {
return singleton;
}
}
}
}
用CAS的好处在于不需要使用传统的锁机制来保证线程安全,CAS是一种基于忙等待的算法,依赖底层硬件的实现,相对于锁它没有线程切换和阻塞的额外消耗,可以支持较大的并行度。
CAS的一个重要缺点在于如果忙等待一直执行不成功(一直在死循环中),会对CPU造成较大的执行开销。而且,这种写法如果有多个线程同时执行singleton = new Singleton();也会比较浪费堆内存。
Java 多线程(四)—— 单例模式的更多相关文章
- java 多线程四
java 多线程一 java 多线程二 java 多线程三 java 多线程四 一个生产者,消费者的例子: import java.util.Stack; /** * Created by root ...
- java多线程(四)-自定义线程池
当我们使用 线程池的时候,可以使用 newCachedThreadPool()或者 newFixedThreadPool(int)等方法,其实我们深入到这些方法里面,就可以看到它们的是实现方式是这样的 ...
- java多线程与单例模式(Singleton)不得不说的故事
转发自:http://blog.csdn.net/ligang7560/article/details/50890282 单例模式的多种实现方式 我们都知道单例模式有几种常用的写法: - 饿汉模式 - ...
- Java多线程(四) 线程池
一个优秀的软件不会随意的创建.销毁线程,因为创建和销毁线程需要耗费大量的CPU时间以及需要和内存做出大量的交互.因此JDK5提出了使用线程池,让程序员把更多的精力放在业务逻辑上面,弱化对线程的开闭管理 ...
- java多线程四种实现模板
假设一个项目拥有三块独立代码块,需要执行,什么时候用多线程? 这些代码块某些时候需要同时运行,彼此独立,那么需要用到多线程操作更快... 这里把模板放在这里,需要用的时候寻找合适的来选用. 总体分为两 ...
- Java多线程(四) —— 线程并发库之Atomic
一.从原子操作开始 从相对简单的Atomic入手(java.util.concurrent是基于Queue的并发包,而Queue,很多情况下使用到了Atomic操作,因此首先从这里开始). 很多情况下 ...
- java多线程环境单例模式实现详解
Abstract 在开发中,如果某个实例的创建需要消耗很多系统资源,那么我们通常会使用惰性加载机制,也就是说只有当使用到这个实例的时候才会创建这个实例,这个好处在单例模式中得到了广泛应用.这个机制在s ...
- java 多线程,单例模式类(创建对象)最优写法
单例模式 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 这种模式涉及到一个单一的类,该类负责创 ...
- Java多线程之单例模式(线程安全)
package org.study2.javabase.ThreadsDemo.sync; /** * @Auther:GongXingRui * @Date:2018/9/20 * @Descrip ...
- java多线程(四)之同步机制
1.同步的前提 多个线程 多个线程使用的是同一个锁 2.同步的好处 同步的出现解决了多线程的安全问题 3.同步的弊端 当线程较多时, 因为每个线程都会去判断同步上的锁, 这样是很耗费资源的, 会降低程 ...
随机推荐
- python入门编程之mysql编程
python关于mysql方面的连接编程 前提:引入mysql模块MySQLdb,即:MySQL_python-1.2.5-cp27-none-win_amd64.whl 如果要用线程池,则要引用模块 ...
- 五、OpenStack—nova组件介绍与安装
一.nova介绍 Nova 是 OpenStack 最核心的服务,负责维护和管理云环境的计算资源.OpenStack 作为 IaaS 的云操作系统,虚拟机生命周期管理也就是通过 Nova 来实现的. ...
- mongodbwindows安装过程附带安装包百度云
1.mongodb安装包链接 链接:https://pan.baidu.com/s/1bxZ2oV-iJEs7RoH5kN6jVg 密码:ajuj 2.配置准备,创建文件夹及文件: 目录为: \ ...
- VS 2013Ultimate 开发过程中遇到的问题——listbox的隐藏问题,combobox.textchanged的中文问题
最近项目有需求,就是把一个combobox让它可以根据用户输入的汉字就行模糊查询出匹配的下拉框内容,很简单,是吧 但是!!!在开发中真是遇到了不少问题呢. 一.实现流程 1)我的实现思维是这样的,先把 ...
- Js闭包应用场合,为vue的watch加上一个延迟器
利用vue的watch可以很简单的监听数据变化 而watch来侦听数据继而调用业务逻辑是一种十分常见的模式 最典型的就是自动搜索功能,如下图,这里我们用watch侦听被双向绑定的input值,而后触发 ...
- Nuxt.js 从入门到放弃
Nuxt 是 Vue 上的 SSR,也就是服务端渲染应用框架,可在很大程度上解决当前 SPA 和 CSR 的首页加载慢,不利于 SEO 的问题.本场 Chat 就将详细介绍 Nuxt 的使用以及相关概 ...
- Fio测试工具参数
以随机读为例:fio -ioengine=libaio -group_reporting -direct=1 -name=testsda -numjobs=1 --time_based --runti ...
- Vue知识点总结
1.属性名已$开头的都是内部提供的属性 2.为什么使用事件修饰符的原因:methods 只有纯粹的数据逻辑,而不是去处理 DOM 事件细节 3.v-if 如果值为false,元素在页面中不存在:值为t ...
- HTML入门10
目前,掌握了图像,视频和音频的嵌入,下面来谈iframe和embed.object嵌入网页, 嵌入简史,刚开始流行用嵌入框架然后不同部分显示i不同内容,可以解决下载速度慢时的问题: 慢慢的插件技术流行 ...
- 1、了解计算机与操作系统发展阶段 2、选择一个具体的操作系统,结合计算机与操作系统的发展阶段,详细了解其渊源、发展过程、趋势,整理成简洁美观的图文博客发布。 Windows Mac os x Unix Linux Android 等。
1.了解计算机与操作系统发展阶段 操作系统并不是与计算机硬件一起诞生的,它是在人们使用计算机的过程中,为了满足两大需求:提高资源利用率.增强计算机系统性能,伴随着计算机技术本身及其应用的日益发展,而逐 ...