java 多线程并发问题
2024-10-08 10:51:33
问题: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());
注意:线程池的用法
最新文章
- Make Notepad++ auto close HTML/XML tags after the slash(the Dreamweaver way)
- Ubuntu下安装Pyenv不成功,求指教
- BackGroundWorker控件的使用注意
- make no mistake, we are the last line of defense.
- JSTL、EL、ONGL、Struts标签的区别与使用
- Java语言中有4种访问修饰符
- HTTP Get与Post的本质区别
- python range的用法小题
- pymysql-python爬虫数据存储准备
- C#词频统计 效能分析
- LeetCode题库13. 罗马数字转整数(c++实现)
- Android无线调试_adbWireless
- ios上-webkit-overflow-scrolling与position的bug
- js 日期,时间函数 及相关运算大全
- YARN的重启动问题:RM Restart/RM HA/Timeline Server/NM Restart
- 系统管理员应该知道的20条Linux命令
- WPF ComboBox下拉绑定Treeview 功能的实现
- idea结合git使用三
- 使用spring,pageHelper ,注解完成分页。
- 如何最快地实现 ALTER TABLE