有如下代码:
public class NameAndPsw {
private String name = "name";
private String psw = "psw";
synchronized public void setsth (String n,String p){
this.name = n;
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.psw = p;
System.out.println("更新操作完成!");
}
synchronized public void getsth(){
System.out.println("name:"+name+" psw:"+psw);
}
}
public class ThreadA extends Thread{
NameAndPsw nameAndPsw;
public ThreadA(NameAndPsw n){
this.nameAndPsw = n;
}
@Override
public void run() {
nameAndPsw.setsth("new name","new psw");
}
}
public class ThreadB extends Thread{
NameAndPsw nameAndPsw;
public ThreadB(NameAndPsw n){
this.nameAndPsw = n;
}
@Override
public void run() {
nameAndPsw.getsth();
}
}
public class Main {
public static void main(String[] args) {
NameAndPsw nameAndPsw = new NameAndPsw();
Thread threadA = new ThreadA(nameAndPsw);
Thread threadB = new ThreadB(nameAndPsw);
threadA.start();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
threadB.start();
}
}
有NameAndPsw类,其中有更新用户名密码的函数,有获取用户名密码的函数。
A线程更新用户名密码,B线程获取用户名密码。
这里使用synchronized避免了读取脏数据的情况。
如果没有加上synchronize关键字,更新用户名密码的过程中,线程睡眠了,此时获取用户名密码的线程去执行。就会出现脏读现象。
加上该关键字之后,因为拥有了对象锁,所以读取线程并不能执行,不会出现脏读现象。
使用synchronized关键字同步一个明显的特点是:MyObject类中定义有多个synchronized修饰的实例方法时,若多个线程拥有同一个MyObject类的对象,则这些方法只能以同步的方式执行。即,执行完一个synchronized修饰的方法后,才能执行另一个synchronized修饰的方法。