当一个线程运行修改数据的方法,另一个线程启动读取数据的值,会读到未修改的前的数据
package com.jc.thread;
public class Thread04 {
private String name = "abc";
private String password = "123";
public synchronized void setValue(String name, String password) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.name = name;
this.password = password;
}
public void getValue() {
System.out.println(this.name);
System.out.println(this.password);
}
public static void main(String[] args) {
final Thread04 thread04 = new Thread04();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
thread04.setValue("jkl", "333");
}
}, "t1");
t1.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
thread04.getValue();
}
}
输出结果为:
abc
123
对于对象的同步或者异步方法,我们在设计程序的时候一定要考虑整体性,不然会出现不一致的问题,很经典的错误就是脏读,当setValue()和getValue()同时加上synchronized 关键字,保证了业务的原子性。
package com.jc.thread;
public class Thread04 {
private String name = "abc";
private String password = "123";
public synchronized void setValue(String name, String password) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.name = name;
this.password = password;
}
public synchronized void getValue() {
System.out.println(this.name);
System.out.println(this.password);
}
public static void main(String[] args) {
final Thread04 thread04 = new Thread04();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
thread04.setValue("jkl", "333");
}
}, "t1");
t1.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
thread04.getValue();
}
}
输出结果为:
jkl
333