一:脏读,对于数据的读取没有做到一致性,正如下面的例子,两个线程同时操作一个对象,一个线程设置对象的值,
另一个线程读取对象的值,但是在第一个线程没有设置完成时(业务逻辑处理时间比较长),第二个线程就开始获取
数据了,所以会出现问题。
/**
*
*/
package com.day2;
/**
* @author Administrator
* 脏读,对于数据的读取没有做到一直性,正如下面的例子,两个线程同时操作一个对象,一个线程设置对象的值,
* 另一个线程读取对象的值,但是在第一个线程没有设置完成时(业务逻辑处理时间比较长),第二个线程就开始获取
* 数据了,所以会出现问题。
*/
public class MutiThread {
private String username = "root";
private String password = "1234";
public synchronized void setValue(String username, String password) {
this.username = username;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.password = password;
System.out.println("最终结果:用户名" + this.username + "密码:" + this.password);
}
public void getValue() {
System.out.println("获取结果:用户名" + this.username + "密码:" + this.password);
}
public static void main(String[] args) {
final MutiThread task = new MutiThread();
// 线程1set数据
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
task.setValue("mysql", "4567");
}
});
t1.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
task.getValue();
}
}
运行结果:
获取结果:用户名mysql密码:1234 最终结果:用户名mysql密码:4567
出现错误,实际上想获取的是最终结果,但是由于setValue()处理逻辑时间比较长,这个时候就来获取值getValue(),
所以出现错误,为了避免这种情况,对于相同的业务,set与get应该做到同步,都加上synchronized锁
public synchronized void setValue(String username, String password) {
this.username = username;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.password = password;
System.out.println("最终结果:用户名" + this.username + "密码:" + this.password);
}
public synchronized void getValue() {
System.out.println("获取结果:用户名" + this.username + "密码:" + this.password);
}
运行结果:
最终结果:用户名mysql密码:4567 获取结果:用户名mysql密码:4567
这次运行结果正确!
原文:http://www.cnblogs.com/warrior4236/p/7203236.html