JAVA多執行緒關鍵字synchronize的使用方法
阿新 • • 發佈:2019-02-12
這裡通過對一個銀行存錢取錢程式的模擬去演示在使用多執行緒的時候synchronize關鍵字的作用。
1. 不加同步鎖的程式碼
package threadTest;
public class Bank {
private int count =0;//賬戶餘額
//存錢
public void addMoney(int money){
count +=money;
System.out.println(System.currentTimeMillis()+"存進:"+money);
}
//取錢
public void subMoney(int money){
if(count-money < 0){
System.out.println("餘額不足");
return;
}
count -=money;
System.out.println(+System.currentTimeMillis()+"取出:"+money);
}
//查詢
public void lookMoney(){
System.out.println("賬戶餘額:"+count);
}
public static void main(String args[]){
final Bank bank=new Bank();
Thread tadd=new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bank.addMoney(100);
bank.lookMoney();
System.out.println("\n");
}
}
});
Thread tsub = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
bank.subMoney(100);
bank.lookMoney();
System.out.println("\n");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
tsub.start();
tadd.start();
}
}
可以看到結果完全是混亂的,因為存錢取錢的執行緒是同步的,但是變數只有一個,因此他就萌幣了,因為兩個人一直不停的在修改他。
解決方法是在兩個run方法前加了加了synchronize之後,就可以正常使用了。
public synchronized void run() {
而在存、取方法前加也是效果一樣的
//取錢
public void subMoney(int money){
synchronized (this) {
if(count-money < 0){
System.out.println("餘額不足");
return;
}
count -=money;
}
System.out.println(+System.currentTimeMillis()+"取出:"+money);
}
注:同步是一種高開銷的操作,因此應該儘量減少同步的內容。通常沒有必要同步整個方法,使用synchronized程式碼塊同步關鍵程式碼即可。