java 多线程并发问题
问题:50个线程,先查询数据库的一个记录 t,然后对这个记录+1,最后更新到数据库
(更新的时候,不允许使用 update test_concurrent set sum =sum -1 where id=1,如果这个做就看不出来效果了,必须使用update test_concurrent set sum =? where id=1)。
1.创建表
CREATE TABLE `test_concurrent` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`sum` bigint(20) DEFAULT NULL COMMENT '并发的和',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
2.表里只有一条记录
INSERT INTO `test_concurrent` VALUES (1, 0);
对于这种并发问题有三种解决方法
1.使用悲观锁 select for update
2.使用乐观锁 新增一个字段,查询时设置这个字段,更新时根据这个字段更新
3.update test_concurrent set sum =? where id=1 and sum =#{t}
4.update test_concurrent set sum =sum-? where id=1 and sum >=?
总和来说:4是最好的写法。
并发线程代码
@Test
public void testAdd1() {
log.info("开始执行----------------");
CountDownLatch latch = new CountDownLatch(50); ExecutorService executor=new ThreadPoolExecutor(10, 50, 2000, TimeUnit.SECONDS, new ArrayBlockingQueue(50));
AtomicInteger integer=new AtomicInteger(0);
for(int i=0;i<50;i++){
Integer s=i;
executor.execute(new Runnable() {
@Override
public void run() {
//log.info("开始执行----------------{}",s);
service.add1(1);
log.info("开始执行----------------{}",s);
integer.incrementAndGet();
latch.countDown();
}
}); }
try {
latch.await();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
log.info("开始执行----------------{}",integer.intValue());
注意:线程池的用法

java 多线程并发问题的更多相关文章
- Java多线程-并发容器
Java多线程-并发容器 在Java1.5之后,通过几个并发容器类来改进同步容器类,同步容器类是通过将容器的状态串行访问,从而实现它们的线程安全的,这样做会消弱了并发性,当多个线程并发的竞争容器锁的时 ...
- Java 多线程并发编程一览笔录
Java 多线程并发编程一览笔录 知识体系图: 1.线程是什么? 线程是进程中独立运行的子任务. 2.创建线程的方式 方式一:将类声明为 Thread 的子类.该子类应重写 Thread 类的 run ...
- Java多线程并发技术
Java多线程并发技术 参考文献: http://blog.csdn.net/aboy123/article/details/38307539 http://blog.csdn.net/ghsau/a ...
- java 多线程并发问题总结
java 多线程并发主要通过关键字synchronized实现 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问 ...
- 从火箭发场景来学习Java多线程并发闭锁对象
从火箭发场景来学习Java多线程并发闭锁对象 倒计时器场景 在我们开发过程中,有时候会使用到倒计时计数器.最简单的是:int size = 5; 执行后,size—这种方式来实现.但是在多线程并发的情 ...
- Java多线程并发03——在Java中线程是如何调度的
在前两篇文章中,我们已经了解了关于线程的创建与常用方法等相关知识.接下来就来了解下,当你运行线程时,线程是如何调度的.关注我的公众号「Java面典」了解更多 Java 相关知识点. 多任务系统往往需要 ...
- Java多线程并发02——线程的生命周期与常用方法,你都掌握了吗
在上一章,为大家介绍了线程的一些基础知识,线程的创建与终止.本期将为各位带来线程的生命周期与常用方法.关注我的公众号「Java面典」了解更多 Java 相关知识点. 线程生命周期 一个线程不是被创建了 ...
- Java多线程并发05——那么多的锁你都了解了吗
在多线程或高并发情境中,经常会为了保证数据一致性,而引入锁机制,本文将为各位带来有关锁的基本概念讲解.关注我的公众号「Java面典」了解更多 Java 相关知识点. 根据锁的各种特性,可将锁分为以下几 ...
- Java多线程并发04——合理使用线程池
在此之前,我们已经了解了关于线程的基本知识,今天将为各位带来,线程池这一技术.关注我的公众号「Java面典」了解更多 Java 相关知识点. 为什么使用线程池?线程池做的工作主要是控制运行的线程的数量 ...
- Java多线程并发07——锁在Java中的实现
上一篇文章中,我们已经介绍过了各种锁,让各位对锁有了一定的了解.接下来将为各位介绍锁在Java中的实现.关注我的公众号「Java面典」了解更多 Java 相关知识点. 在 Java 中主要通过使用sy ...
随机推荐
- ASP.NET Identity系列教程-1目录
https://www.cnblogs.com/hao-1234-1234/p/8857437.html ASP.NET Identity系列教程 13 Getting Started with Id ...
- MySQL数据库重点监控指标
MySQL数据库重点监控指标 QPS queries per seconds 每秒中查询数量 show global status like 'Question%'; Queries/seconds ...
- Linux system basic 2 + add kernel for Jupyter
Linux install LibreOffice: install LibreOffice: install command: sudo apt install ./XXX.deb PS: don' ...
- pygame 浅解
import pygame from first_pygame.plane_spirit import * # 调用重载的精灵类 # 初始化 pygame.init() # 初始化所有所需游戏模块 s ...
- MATLAB一些常用的function
在MATLAB中一些常用的算数符号与我们平时所用的不同,比如:根号,平方,e,以及对数函数等. (1)平方:a^2 意思为a的平方,亦可以写成a*a: (2)根号:sqrt(x)意思为对x开根号,x既 ...
- IntelliJ IDEA 2017.3尚硅谷-----取消更新
- DisplayNameFor()方法的工作原理
DisplayNameFor()方法的工作原理原创Peter Yelnav 最后发布于2018-11-23 11:09:51 阅读数 1308 收藏展开最近研究了一下ASP.NET MVC,困惑于视图 ...
- Java-POJ1009-Edge Detection(未完成,有C++代码)
RLE编码,还不会,先搬运一下大佬的代码,理解之后再用Java自己实现 #include <map> #include <vector> #include <cstdli ...
- 代码架构.md
代码架构 待办 昨天待办 decription decription 我的流程逻辑(异常处理方式) 1568097677501.drawio.html 29.94 KB 异常的两种处理方式 异常的两种 ...
- robots.txt 让搜索引擎不再收录网站
有没有担心过自己的隐私会在强大的搜索引擎面前无所遁形?想象一下,如果要向世界上所有的人公开你的私人日记,你能接受吗?的确是很矛盾的问题,站长们大都忧虑“如何让搜索引擎收录的我的网站?”,而我们还是要研 ...