線程安全問題產生的原因:
1,多個線程在操作共享的數據;
2,操作共享數據的線程代碼有多條;
當一個線程在執行操作共享數據的多條代碼過程中,其他線程參與了運算,就會導致線程安全問題的產生。
解決思路:
就是將多條操作共享數據的線程代碼封裝起來,當有線程在執行這些代碼的時候,其他線程是不可以參與運算的。
必需要當前線程把這些帶那都執行完畢后,其他線程才能參與運算。
在java中用同步代碼塊就可以解決這個問題
同步代碼塊的格式:
synchronized(對象){
需要被同步的代碼;
}
同步的好處:解決了線程的安全問題。
同步的弊端:相對降低了效率,因為同步外的線程都會判斷同步鎖。
同步的前提:同步中必須有多個線程並使用同一個鎖。
同步有兩種:
1,同步代碼塊:
class Bank{
private int sum;
public void add(int money){
synchronized(this){
sum += money;
System.out.println(Thread.currentThread().getName()+"********"+"sum = "+sum);
}
}
}
2,同步函數:
e.g.
class Bank{
private int sum;
public synchronized void add(int money){
//synchronized(this){
sum += money;
System.out.println(Thread.currentThread().getName()+"********"+"sum = "+sum);
//}
}
}
同步函數所使用的鎖是this;
同步函數和同步代碼塊的區別:
同步函數的鎖是固定的this;
同步代碼塊的鎖是任意的對象。
建議使用同步代碼塊。
靜態的同步函數使用的鎖是該函數所屬字節碼文件對象
可以用getClass()方法來獲取,也可以用當前 類名.class表示
