Java多线程编程之单例模式
延迟加载:“懒汉模式”
延迟加载是指在调用getInstance()方法时创建实例。常见的方法是在getInstance()方法中实例化new。实现代码如下:

但是因为getInstance()中有多个语句,所以可能存在线程安全问题。运行结果还表明:
2041531420
1348345633
1348345633
即使getInstance()中有更多的语句,也会有三个不同的对象。线程。.(3000)被添加到if(myObject==null)语句块。结果表明:
218620763
58615885
712355351
解决方案:DCL
如果使用synchronized关键字锁定整个getInstance()或整个if语句块,则会存在效率问题。
最后,采用DCL(double-Check Locking)双校验锁定机制,这也是大多数多线程结合单例模式的解决方案。第一层主要是为了避免不必要的同步,第二层是在空情况下创建实例。

测试结果,得到的是相同的hashcode。
立即加载:“饿汉模式”
立即加载意味着在使用类时创建了对象。常见的实现方法是直接新实例化。也就是说,在调用方法之前,创建实例。示例代码如下:
1 class MyObject {
2 private static MyObject myObject=new MyObject();
3 private MyObject(){}
4 public static MyObject getInstance(){
5 //如果还有其他代码,存在线程安全问题
6 return myObject;
7 }
8 }
9 class MyThread extends Thread{
10 @Override
11 public void run() {
12 System.out.println(MyObject.getInstance().hashCode());
13 }
14 }
15 public class Run {
16 public static void main(String[] args) {
17 MyThread t1=new MyThread();
18 MyThread t2=new MyThread();
19 MyThread t3=new MyThread();
20 t1.start();
21 t2.start();
22 t3.start();
23 }
24 }
运行结果如下:

可以发现,实现了单例模式,因为多个线程得到的实例的hashCode是一样的。
静态内置类

采用静态内置类的方法,是线程安全的。
使用static代码块
静态代码块的代码在重用类时执行,因此可以应用静态代码块的这个特性来实现单例设计模式。

使用enum枚举数据类型
当使用枚举类时,类似于静态代码块,自动调用构造函数。枚举由javac编译,并转换为诸如公共最终类T extends Enum之类的定义。也就是说,我们定义的枚举在第一次真正使用时由虚拟机加载和初始化,并且初始化过程是线程安全的。众所周知,解决单例并发问题的主要方法是初始化过程中的线程安全问题。
因此,由于枚举的上述特性,枚举实现了固有的线程安全的单例。同时,枚举可以解决反序列化会破坏单例的问题。
enum MyObject{
INSTANCE;
}
SimpleDataFormat
SimpleDataFormat使用带有线程安全问题的单例模式。SimpleDateFormat中的日期格式不同步。建议(建议)为每个线程创建单独的格式实例。如果多个线程同时访问一种格式,则它必须保持外部同步。
解决方案1:需要的时候创建新实例

在需要SimpleDateFormat的地方创建新实例可以通过在任何时候将线程安全的对象从共享更改为本地私有来避免多线程,但是它也增加了创建对象的负担。一般来说,对性能的影响不是很明显。
解决方案2:同步SimpleDateFormat对象
当有更多的线程时,当一个线程调用此方法时,其他想要调用此方法的线程需要块。当多线程并发性较大时,会对性能产生一定的影响。
解决方案3:使用ThreadLocal

ThreadLocal还用于将共享变量转换为独占变量。ThreadLocal肯定比方法独占性减少了在并发环境中创建对象的开销。如果性能要求很高,通常建议使用这种方法。
Java多线程编程之单例模式的更多相关文章
- Java多线程编程核心技术---单例模式与多线程
立即加载/饿汉模式 立即加载就是使用类的时候已经将对象创建完毕. public class MyObject { //立即加载方式==饿汉模式 private static MyObject myOb ...
- Java多线程编程核心技术
Java多线程编程核心技术 这本书有利于对Java多线程API的理解,但不容易从中总结规律. JDK文档 1. Thread类 部分源码: public class Thread implements ...
- 《Java 多线程编程核心技术》- 笔记
作为业务开发人员,能够在工作中用到的技术其实不多.虽然平时老是说什么,多线程,并发,注入,攻击!但是在实际工作中,这些东西不见得用得上.因为,我们用的框架已经把这些事做掉了. 比如web开发,外面有大 ...
- Java多线程核心技术(五)单例模式与多线程
本文只需要考虑一件事:如何使单例模式遇到多线程是安全的.正确的 1.立即加载 / "饿汉模式" 什么是立即加载?立即加载就是使用类的时候已经将对象创建完毕,常见的实现办法就是直接 ...
- Java多线程编程核心技术(三)多线程通信
线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体.线程间的通信就是成为整体的必用方案之一,可以说,使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时 ...
- Java多线程编程核心技术(二)对象及变量的并发访问
本文主要介绍Java多线程中的同步,也就是如何在Java语言中写出线程安全的程序,如何在Java语言中解决非线程安全的相关问题.阅读本文应该着重掌握如下技术点: synchronized对象监视器为O ...
- Java多线程编程核心技术(一)Java多线程技能
1.进程和线程 一个程序就是一个进程,而一个程序中的多个任务则被称为线程. 进程是表示资源分配的基本单位,线程是进程中执行运算的最小单位,亦是调度运行的基本单位. 举个例子: 打开你的计算机上的任务管 ...
- Java多线程编程实战指南(核心篇)读书笔记(二)
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76651408冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...
- 《Java多线程编程核心技术》知识梳理
<Java多线程编程核心技术> @author ergwang https://www.cnblogs.com/ergwang/ 文章末尾附pdf和png下载链接 第1章 Java多线程技 ...
随机推荐
- dotNet Core WEB程序使用 Nginx反向代理
之前记录过一篇 使用 jexus 作为dotNetCore的反向代理,发现jexus的内存占用较大,最终选择使用Nginx的原因就是占用内存较小,以及性能较优(https://www.cnblogs. ...
- centos下配置nginx遇到的一些基本的坑
作为一个用.net的渣渣,常年混迹在window平台下,对Linux啥都不懂.随着.net core开源.跨平台后,也开始学习下linux. 在Desktop/Webs下放了一个index.html的 ...
- Flask系列05--Flask的配置config
一.flask配置 示例说明, 就是使用config进行配置 from flask import Flask app = Flask(__name__) # type:Flask app.conf ...
- Spring static 静态属性注入
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> &l ...
- C#6.0语言规范(十五) 委托
委托启用其他语言(如C ++,Pascal和Modula)已使用函数指针进行寻址的方案.但是,与C ++函数指针不同,委托是完全面向对象的,与成员函数的C ++指针不同,委托封装了对象实例和方法. 委 ...
- while循环中使用scanf函数
妈的,这scanf函数学了快10年了,怎么还会出现莫名其妙的问题?看下面的代码(VS2012环境下运行): #define _CRT_SECURE_NO_WARNINGS #include<st ...
- (转)CentOS一键安装Nginx脚本
原文:https://www.xiaoz.me/archives/10301 https://blog.slogra.com/post-676.html-----centos7一键安装nginx脚本
- python中 =、copy、deepcopy的差别
python2中,需要import copy模块 python3中,直接可以使用copy()方法,但deepcopy()还是需要导入copy模块 下面以python2为例: 对于"=&quo ...
- 【从0到1学jQuery】jQuery中each()和$.each()的使用
引子: 最近遇到一个问题,就是在each()函数中怎么模拟for循环中的break和continue的操作.所以就查看了jQuery关于这个函数的文档,并且总结一下. 演示代码如下: <div& ...
- godaddy 问题
1. 域名被锁,打电话咨询后.说发送被锁的域名到: change@secureserver.net 去解锁.
