多线程读脏数据问题

来源:互联网 发布:怎样创造软件 编辑:程序博客网 时间:2024/06/05 02:33

示例:

package com.线程间通信;

public class DirtyThread {

//两个实例变量
private String name="zhangsan";
private String password="123";

public void setValue(String name, String password){

//先设置name的值
this.name = name;
//在休眠2秒
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

//休眠完了以后,在设置password的值
this.password = password;

System.out.println("setvalue的最终值为:name="+name+",password="+password);

}

//获取值 synchronized关键字解决读脏数据
public void getValue(){
//打印 name 和 password
System.out.println("getValue的值为:name="+name+",password="+password);

}

public static void main(String[] args) throws InterruptedException {

final DirtyThread dt = new DirtyThread();

//开启一个线程
Thread t = new Thread(new Runnable() {

public void run() {
dt.setValue("wangwu", "456");
}
});

t.start();

//main主线程休眠1秒
Thread.sleep(1000);
//main主线程 获取值(解释下:此段代码中有两个线程,主线程和t线程。当t.start开始线程后,
//设置了name属性值后,就休眠了2秒。此时main主线程就休眠了一秒,所以main主线程会得到
//t线程刚刚设置的name属性值,而password的值还是为初始值)
dt.getValue();
}

}

解决上述main主线程读脏数据问题,在getValue方法前加上synchronized关键字。解释:在getValue方法前加synchronized关键字表示,setValue和getValue方法

是同步方法,共享了同一个dt对象锁。当t 线程去setvalue时,上了锁。此时的主线程去getValue是阻塞的,因为t 线程还没有释放锁,当他线程释放了锁后,此时的

setValue处理完了(即password也设置完了)。main主线程获得了锁,去读数据就是最新更新的数据。

总结:

在外面对一个对象的方法加锁的时候,需要考虑业务的整体性。即为setValue和getValue方法同时加锁,synchronized关键字。

保证业务的原子性,不然会出现业务错误。

0 0