1.业务场景简介
保存用户个人设置,一个用户在a表中只能存在一条记录,用户修改记录时,检查如果该记录存在,则修改该数据,如果该记录不存在,则插入一条记录。
2. 问题说明
多线程情况下,会出现一个用户在表中有多条记录存在的情况。
3. 原因解释
比如说并发两个线程A和线程B, 线程A检查记录不存在,准备插入记录,这时CPU切换到线程B,这是线程B检查记录仍是不存在,线程B插入一条数据,线程B结束。然后CPU切换到线程A,A继续插入记录,这是数据库就会有两条记录。
package com.salen.test;
import java.util.concurrent.atomic.AtomicInteger;
public class MultiThreadTest {
//计数器,记录插入次数
static AtomicInteger num = new AtomicInteger(0);
//记录是否存在, 模拟数据库记录,表示某条信息是否存在
static boolean exist = false;
public static void main(String[] args) {
//起20个线程,同时执行检查插入操作
for (int i = 0; i < 20; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
MultiThreadTest test = new MultiThreadTest();
test.generate();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
/**
* 模拟修改一条数据
* 先去检查该数据是否存在,
* 如果该记录存在,则修改该数据,如果数据不存在,则插入一条新的数据
* @throws InterruptedException
*/
private void generate() throws InterruptedException{
if(exist){
Thread.sleep(1000); // 处理业务 100毫秒
System.out.println("record has exist..., update it ");
}else{
Thread.sleep(100); // 处理业务 100毫秒
System.out.println("record not exist..., insert into it, time = " + num.incrementAndGet());
exist = true;
}
}
}
测试结果
record not exist..., insert into it, time = 2
record not exist..., insert into it, time = 3
record not exist..., insert into it, time = 1
record not exist..., insert into it, time = 4
record not exist..., insert into it, time = 5
record not exist..., insert into it, time = 6
record not exist..., insert into it, time = 7
record not exist..., insert into it, time = 8
record not exist..., insert into it, time = 10
record not exist..., insert into it, time = 9
record not exist..., insert into it, time = 11
record not exist..., insert into it, time = 12
record not exist..., insert into it, time = 13
record not exist..., insert into it, time = 14
record not exist..., insert into it, time = 15
record not exist..., insert into it, time = 17
record not exist..., insert into it, time = 16
record not exist..., insert into it, time = 18
record not exist..., insert into it, time = 19
record not exist..., insert into it, time = 20