java 下单并发_在高并发下,提交订单,怎么保证线程安全?

本文介绍了Java中单例模式的实现方式,包括饿汉式、懒汉式及其线程安全问题。通过同步锁机制、Double Check Locking(DCL)和静态内部类等方式保证了在高并发下的线程安全性。同时,文章讨论了序列化与反序列化对单例的影响以及解决方案,最后提到了使用枚举和静态代码块来实现线程安全的单例模式。
摘要由CSDN通过智能技术生成

单列模式下是可以保证的.

在所有的设计模式中,单例模式是我们在项目开发中最为常见的设计模式之一,而单例模式有很多种实现方式,你是否都了解呢?高并发下如何保证单例模式的线程安全性呢?如何保证序列化后的单例对象在反序列化后任然是单例的呢?

什么是单例模式?

在文章开始之前我们还是有必要介绍一下什么是单例模式。单例模式是为确保一个类只有一个实例,并为整个系统提供一个全局访问点的一种模式方法。

从概念中体现出了单例的一些特点:

(1)、在任何情况下,单例类永远只有一个实例存在

(2)、单例需要有能力为整个系统提供这一唯一实例

各式各样的单例实现

1、饿汉式单例

饿汉式单例是指在方法调用前,实例就已经创建好了。下面是实现代码:

package org.mlinge.s01;

public class MySingleton {

private static MySingleton instance = new MySingleton();

private MySingleton(){}

public static MySingleton getInstance() {

return instance;

}

}

以上是单例的饿汉式实现,我们来看看饿汉式在多线程下的执行情况,给出一段多线程的执行代码:

package org.mlinge.s01;

public class MyThread extends Thread{

@Override

public void run() {

System.out.println(MySingleton.getInstance().hashCode());

}

public static void main(String[] args) {

MyThread[] mts = new MyThread[10];

for(int i = 0 ; i < mts.length ; i++){

mts[i] = new MyThread();

}

for (int j = 0; j < mts.length; j++) {

mts[j].start();

}

}

}

以上代码运行结果:

1718900954

1718900954

1718900954

1718900954

1718900954

1718900954

1718900954

1718900954

1718900954

1718900954

从运行结果可以看出实例变量额hashCode值一致,这说明对象是同一个,饿汉式单例实现了。

2、懒汉式单例

懒汉式单例是指在方法调用获取实例时才创建实例,因为相对饿汉式显得“不急迫”,所以被叫做“懒汉模式”。下面是实现代码:

package org.mlinge.s02;

public class MySingleton {

private static MySingleton instance = null;

private MySingleton(){}

public static MySingleton getInstance() {

if(instance == null){//懒汉式

instance = new MySingleton();

}

return instance;

}

}

这里实现了懒汉式的单例,但是熟悉多线程并发编程的朋友应该可以看出,在多线程并发下这样的实现是无法保证实例实例唯一的,甚至可以说这样的失效是完全错误的,下面我们就来看一下多线程并发下的执行情况,这里为了看到效果,我们对上面的代码做一小点修改:

package org.mlinge.s02;

public class MySingleton {

private static MySingleton instance = null;

private MySingleton(){}

public static MySingleton getInstance() {

try {

if(instance != null){//懒汉式

}else{

//创建实例之前可能会有一些准备性的耗时工作

Thread.sleep(300);

instance = new MySingleton();

}

} catch (InterruptedException e) {

e.printStackTrace();

}

return instance;

}

}

这里假设在创建实例前有一些准备性的耗时工作要处理,多线程调用:

package org.mlinge.s02;

public class MyThread extends Thread{

@Override

public void run() {

System.out.println(MySingleton.getInstance().hashCode());

}

public static void main(String[] args) {

MyThread[] mts = new MyThread[10];

for(int i = 0 ; i < mts.length ; i++){

mts[i] = new MyThread();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值