有如下代碼:
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修飾的方法。