`

实现Java高并发隔离 模拟

    博客分类:
  • java
 
阅读更多

package org;

import java.util.Random;

public class MockMain {
//交易总金额
public static int money =0;

public static void main(String[] args) {
//模拟多线程,
for(int i=0;i<5;i++){
new Thread(new Runnable() {
public void run() {
//商品金额
money = new Random().nextInt(500);
System.out.println("main 线程id:"+Thread.currentThread().getId()
+";商品金额:"+MockMain.money);

//检查账号金额是否大于商品金额
AccountMoney account = new AccountMoney();
account.check();
//扣款
LoseMoney lose = new LoseMoney();
lose.outMoney();
}
}).start();
}
}


}



package org;

public class AccountMoney {

public void check(){
System.out.println("线程id:"+Thread.currentThread().getId()
+";商品金额:"+MockMain.money);
}
}

package org;
public class LoseMoney {
public void outMoney(){
System.out.println("线程id:"+Thread.currentThread().getId()
+";扣款金额:"+MockMain.money);
}

}



输出日志:
main 线程id:10;商品金额:141
main 线程id:9;商品金额:130
main 线程id:11;商品金额:51
main 线程id:12;商品金额:51
线程id:10;商品金额:51
线程id:8;商品金额:51
线程id:12;商品金额:51
线程id:9;商品金额:51
线程id:11;商品金额:51
线程id:12;扣款金额:51
线程id:11;扣款金额:51
线程id:8;扣款金额:51
线程id:10;扣款金额:51
线程id:9;扣款金额:51

从日志中可以看出,线程中检查的金额 ,扣除的金额是不对的。 线程10 的商品金额应该为:141,但是检查和扣除是变成了51; 线程9 的商品金额应该为:130,但是检查和扣除是变成了51 .  线程还没有工作完毕,就被其它的线程打断了,可以考虑加锁看看是否解决 线程和金额混乱的问题。对MockMain 进行修改,修改后如下:



package org;

import java.util.Random;
public class MockMain {
public static final Integer lock =1;
//交易总金额
public static int money =0;

public static void main(String[] args) {
//模拟多线程,
for(int i=0;i<5;i++){
new Thread(new Runnable() {
public void run() {
synchronized (lock) {
//商品金额
money = new Random().nextInt(500);
System.out.println("main 线程id:"+Thread.currentThread().getId()
+";商品金额:"+MockMain.money);

//检查账号金额是否大于商品金额
AccountMoney account = new AccountMoney();
account.check();
//扣款
LoseMoney lose = new LoseMoney();
lose.outMoney();
}
}
}).start();
}
}
}


输出日志:
main 线程id:8;商品金额:439
线程id:8;商品金额:439
线程id:8;扣款金额:439
main 线程id:12;商品金额:172
线程id:12;商品金额:172
线程id:12;扣款金额:172
main 线程id:11;商品金额:300
线程id:11;商品金额:300
线程id:11;扣款金额:300
main 线程id:10;商品金额:128
线程id:10;商品金额:128
线程id:10;扣款金额:128
main 线程id:9;商品金额:459
线程id:9;商品金额:459
线程id:9;扣款金额:459

从日志看,已经可以实现了线程和金额的同步,但是我们添加了锁效率会很低,只有一个线程执行完成后,下一个线程才会执行。有没有更高的效率来实现呢。
我们可以变量和线程绑定试一下。代码修改如下:

package org;

import java.util.Random;
public class MockMain {
public static final Integer lock =1;

public static ThreadLocal<Integer> moneyStore = new ThreadLocal<Integer>();
public static void main(String[] args) {
//模拟多线程,
for(int i=0;i<5;i++){
new Thread(new Runnable() {
public void run() {
//商品金额
Integer money = new Random().nextInt(500);
//变量和线程绑定
moneyStore.set(money);
System.out.println("main 线程id:"+Thread.currentThread().getId()
+";商品金额:"+money +"; moneyStore="+moneyStore.get());

//检查账号金额是否大于商品金额
AccountMoney account = new AccountMoney();
account.check();
//扣款
LoseMoney lose = new LoseMoney();
lose.outMoney();
}
}).start();
}
}
}

package org;
public class AccountMoney {
public void check(){
System.out.println("线程id:"+Thread.currentThread().getId()
+";商品金额:"+MockMain.moneyStore.get());
}
}

package org;
public class LoseMoney {
public void outMoney(){
System.out.println("线程id:"+Thread.currentThread().getId()
+";扣款金额:"+MockMain.moneyStore.get());
}
}




日志输出:
main 线程id:10;商品金额:320; moneyStore=320
main 线程id:11;商品金额:252; moneyStore=252
main 线程id:8;商品金额:116; moneyStore=116
main 线程id:12;商品金额:56; moneyStore=56
线程id:11;商品金额:252
线程id:12;商品金额:56
线程id:10;商品金额:320
线程id:9;商品金额:468
线程id:8;商品金额:116
线程id:11;扣款金额:252
线程id:10;扣款金额:320
线程id:9;扣款金额:468
线程id:8;扣款金额:116
线程id:12;扣款金额:56

从日志看,线程是并发的,是同时进行的,金额和线程没有混乱,因为没有使用锁,并发效率很高。
因此,使用这种方法实现高并发是安全可靠的。
分享到:
评论

相关推荐

    ssm+mysql+Redis实现简易的高并发模拟

    在本项目中,"ssm+mysql+Redis实现简易的高并发模拟" 是一个典型的Web应用架构,用于处理大量并发请求。SSM是Spring、Spring MVC和MyBatis的缩写,这是一种流行的Java Web开发框架组合,而MySQL是常用的开源关系型...

    高并发秒杀案例

    这里,我们将围绕“高并发秒杀案例”这一主题,结合使用SpringMVC和Mybatis两大技术框架,深入探讨如何设计和实现一个能够承受高并发压力的秒杀功能。 首先,我们需要理解SpringMVC作为一款强大的Web MVC框架,它...

    java 数据库实现(设计模拟DBMS)

    在Java中实现数据库,即设计和模拟一个DBMS(数据库管理系统),是一项复杂而有挑战性的任务,涉及到数据存储、查询处理、事务管理等多个关键模块。下面我们将深入探讨这个主题,了解如何利用Java来构建这样的系统。...

    Java语言实现的人工免疫入侵检测框架

    Java语言实现的人工免疫入侵检测框架是一种利用计算机科学中的生物免疫原理来构建的网络安全系统。该框架通过模拟生物免疫系统的机制,对网络流量和系统行为进行监控,以便识别并阻止潜在的恶意活动。以下是该框架...

    爱知之星java工程师面试题模拟题附答案

    - **Redis的数据结构**:Redis支持多种数据结构,如字符串、哈希表、列表、集合和有序集合等,这些数据结构在高并发场景下非常有用。 通过上述总结,我们可以看出这份模拟题覆盖了Java编程中的多个核心领域,对于...

    银行管理系统(JAVA实现的)

    【银行管理系统(JAVA实现的)】是一个基于Java技术构建的应用程序,主要用于模拟并管理银行的各种业务操作。在这样的系统中,通常会包含用户账户管理、存款与取款、转账、贷款处理、利息计算以及报表生成等功能。...

    Java日记-我的学习心得

    3. **简化编程模型**:多线程编程可以更加直观地模拟现实生活中的并发场景,简化程序设计。 #### 四、多线程的实现方式 文章中提到了两种实现多线程的方法:使用多个进程和使用线程。 1. **多个进程**: - **定义...

    java面试评价表

    - **单线程并发处理**:探究Redis单进程单线程架构如何支撑高并发访问。 - **Redis分布式锁**:介绍如何利用Redis实现分布式锁,以及操作的原子性保障机制。 #### 九、项目经验 - **项目架构与技术选型**:分享...

    计算机等级考试二级java模拟题十六.pdf

    在计算机等级考试二级Java模拟题中,涉及到的知识点广泛,涵盖了数据结构、软件设计、语法细节、多线程并发控制以及Java的特定类和接口。下面是对这些知识点的详细解释: 1. 数据结构与二分查找:二分查找是一种...

    Java测试项目.zip

    9. **性能测试**:对于某些项目,可能还需要进行性能测试,如压力测试、负载测试,以检查系统在高并发或大数据量下的表现。JMeter、 Gatling等工具可用于这类测试。 10. **日志和调试**:在测试过程中,日志记录和...

    2021Java大厂面试题——大厂真题之蚂蚁金服-Java高级.pdf

    例如,在单核处理器上,虽然无法真正实现并行执行,但可以通过切换不同的线程来模拟多个任务的并发执行。 - **并行**:指的是多个任务能够同时执行的能力,这通常需要多核处理器的支持。与并发相比,并行能够实现...

    JAVA编程模式与范例_高级应用开发

    - **接口隔离原则**:客户端不应该依赖它不需要的接口。 - **迪米特法则**:一个对象应该对其他对象有最少的了解。 3. **并发编程**: - **线程安全**:如何在多线程环境下确保数据一致性。 - **锁机制**:如...

    航空售票系统源码Java

    JUnit是Java常用的单元测试框架,而Mockito可以帮助模拟协作对象,便于进行隔离测试。 10. **持续集成/持续部署(CI/CD)**:为了快速迭代和优化系统,CI/CD流程是现代软件开发的标准实践。Jenkins或GitLab CI/CD...

    java项目设计与开发范例

    JUnit是Java的单元测试框架,而Mockito等工具可以帮助模拟依赖以进行隔离测试。 12. **持续集成/持续部署(CI/CD)**: Jenkins、GitLab CI/CD等工具使得代码构建、测试和部署自动化,提高了开发效率和软件质量。 13...

    Java架构师技术栈.txt

    互联网高并发解决方案-基于Hystrix实现服务隔离与降级 ,9.互联网安全架构-Web常用攻击手段之防盗链&防止CSRF模拟请求............12分布式解决方案-分布式配置中心-SpringBoot客户端整合Apollo分布式配置中心.........

    Java高级试听课:MySQL锁和事务篇.txt

    - **行级锁**:锁定特定行,开销小,发生死锁的概率较低,但并发度较高。 - **表级锁**:锁定整个表,开销小,加锁快,但并发度低。 - **页级锁**:锁定数据页,开销和加锁时间介于行级和表级之间,适用于BLOB或TEXT...

    java做的简单的银行系统

    Java支持多线程,可以用来模拟并发交易,确保在高并发环境下的数据一致性。事务管理(ACID特性:原子性、一致性、隔离性和持久性)也是银行系统的重要组成部分,Java的JTA(Java Transaction API)可以协助实现这...

    基于java的聊天系统的设计于实现(系统+文).zip

    JUnit是常用的Java单元测试框架,而Mockito等工具可用于模拟依赖项,进行隔离测试。 10. **部署与运维**:完成开发后,系统需要部署到服务器上,可能涉及到Tomcat、Jetty等应用服务器。监控和日志收集工具,如...

    JAVA中里10种常见库.zip

    SLF4J是一个日志抽象层,允许开发者在不修改代码的情况下切换不同的日志实现,如Log4j或Java内置的日志系统。 10. **Hibernate**: Hibernate是一个对象关系映射(ORM)框架,它简化了Java应用与数据库的交互。...

Global site tag (gtag.js) - Google Analytics