延迟加载:“懒汉模式”

延迟加载是指在调用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多线程编程之单例模式的更多相关文章

  1. Java多线程编程核心技术---单例模式与多线程

    立即加载/饿汉模式 立即加载就是使用类的时候已经将对象创建完毕. public class MyObject { //立即加载方式==饿汉模式 private static MyObject myOb ...

  2. Java多线程编程核心技术

    Java多线程编程核心技术 这本书有利于对Java多线程API的理解,但不容易从中总结规律. JDK文档 1. Thread类 部分源码: public class Thread implements ...

  3. 《Java 多线程编程核心技术》- 笔记

    作为业务开发人员,能够在工作中用到的技术其实不多.虽然平时老是说什么,多线程,并发,注入,攻击!但是在实际工作中,这些东西不见得用得上.因为,我们用的框架已经把这些事做掉了. 比如web开发,外面有大 ...

  4. Java多线程核心技术(五)单例模式与多线程

    本文只需要考虑一件事:如何使单例模式遇到多线程是安全的.正确的 1.立即加载 / "饿汉模式" 什么是立即加载?立即加载就是使用类的时候已经将对象创建完毕,常见的实现办法就是直接 ...

  5. Java多线程编程核心技术(三)多线程通信

    线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体.线程间的通信就是成为整体的必用方案之一,可以说,使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时 ...

  6. Java多线程编程核心技术(二)对象及变量的并发访问

    本文主要介绍Java多线程中的同步,也就是如何在Java语言中写出线程安全的程序,如何在Java语言中解决非线程安全的相关问题.阅读本文应该着重掌握如下技术点: synchronized对象监视器为O ...

  7. Java多线程编程核心技术(一)Java多线程技能

    1.进程和线程 一个程序就是一个进程,而一个程序中的多个任务则被称为线程. 进程是表示资源分配的基本单位,线程是进程中执行运算的最小单位,亦是调度运行的基本单位. 举个例子: 打开你的计算机上的任务管 ...

  8. Java多线程编程实战指南(核心篇)读书笔记(二)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76651408冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  9. 《Java多线程编程核心技术》知识梳理

    <Java多线程编程核心技术> @author ergwang https://www.cnblogs.com/ergwang/ 文章末尾附pdf和png下载链接 第1章 Java多线程技 ...

随机推荐

  1. HttpURLConnection与HttpClient随笔

    目前在工作中遇到的需要各种对接接口的工作,需要用到HTTP的知识,工作完成后想要做一些笔记,本来知识打算把自己写的代码粘贴上来就好了,但是偶然发现一篇博文对这些知识的总结非常到位,自认无法写的这么好, ...

  2. C++获取系统信息(IP地址、硬件信息等)

    #include<stdio.h> #include<winsock2.h> //该头文件需在windows.h之前 #include<windows.h> #in ...

  3. GoLang学习之数据类型

    数据类型 Go语言按类别有以下几种数据类型: bool,一个字节,值是true或者false,不可以用0或者1表示 int/uint(带符号为与不带符号位的int类型):根据平台不同是32位或者64位 ...

  4. 简单记录常用git 命令

    声明:仅作笔记用 拉取远程代码 1.git pull 2.如果需要,输入账户名密码 将本地代码推送到远程 1.git push 2.如果需要,输入账户名密码 同步远程分支 1.git fetch 2. ...

  5. flask框架--cookie,session

    今天我又给大家分享一下怎么用flask框架来实现像淘宝购物车一样存储数据,并且把存储的数据删除,这个方法可以用两个方法都可以做成,一个是cookie,另一个是session. session是依赖于c ...

  6. 机器学习与Tensorflow(1)——机器学习基本概念、tensorflow实现简单线性回归

    一.机器学习基本概念 1.训练集和测试集 训练集(training set/data)/训练样例(training examples): 用来进行训练,也就是产生模型或者算法的数据集 测试集(test ...

  7. gensim与numpy array 互转

    目的 将gensim输出的格式转化为numpy array格式,支持作为scikit-learn,tensorflow的输入 实施 使用nltk库的停用词和网上收集的资料整合成一份新的停用词表,用来过 ...

  8. Vim实用技巧系列 - tab和空格的转换

    有时候,我们会修改一些代码,而这些代码中的tab设定和我们自己的设定不一样.例如,我们自己的设定是以两个空格来代替tab,而要修改的代码则是使用tab.那么,我们应该怎样快速的将又有的tab转换为空格 ...

  9. 基于GTK+3 开发远程控制管理软件(C语言实现)系列 一 开篇

    近期趁公司没项目来,想学习一下C和GTK+3 ,顺道再学习一下Linux下有关网络编程方面的知识. 一.学习知识: 1.C基本语法 2.GTK+3 API学习 GUI相关知识学习 3.Glade使用及 ...

  10. 公共技术点(Android 动画基础)

    转载地址:http://p.codekk.com/blogs/detail/559623d8d6459ae793499787 一 传统 View 动画(Tween/Frame) 1.1 Tween 动 ...