什么是脏读
什么是脏读
- 本次事务访问到了其他事务未提交的数据
代码
service.java
package com.service;
import java.util.ArrayList;
import java.util.List;
/**
* 脏读
*/
public class Service {
private List<Object> lists = new ArrayList<Object>();
public void print() throws InterruptedException {
lists.add("abc");
System.out.println("休息5秒钟,制造脏读场景大小是:" + lists.size());
Thread.sleep(5000);
lists.remove("abc");
System.out.println("回退操作:" + lists.size());
}
public int getSize() {
return lists.size();
}
}
ThreadA.java
package com.service;
public class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
this.service = service;
}
@Override
public void run() {
try {
Thread.sleep(200);
int size = service.getSize();
System.out.println(Thread.currentThread().getName()+ "->读取到的大小是:"+size);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
ThreadB.java
package com.service;
public class ThreadB extends Thread {
private Service service;
public ThreadB(Service service){
this.service = service;
}
@Override
public void run() {
System.out.println("开始增加");
try {
service.print();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("结束增加");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Run.java
package com.service;
public class Run {
public static void main(String[] args) {
Service service = new Service();
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
}
}
运行结果是:
开始增加
休息5秒钟,制造脏读场景大小是:1
A->读取到的大小是:1
回退操作:0
结束增加
Process finished with exit code 0
解决方法
- 增加锁synchronized
service.java
public class Service {
//线程不安全的类
private List<Object> lists = new ArrayList<Object>();
public void print() throws InterruptedException {
synchronized (Service.class){
lists.add("abc");
System.out.println("休息5秒钟,制造脏读场景大小是:" + lists.size());
Thread.sleep(5000);
lists.remove("abc");
System.out.println("回退操作:" + lists.size());
}
}
public int getSize(){
synchronized (Service.class){
return lists.size();
}
}
}