2016-02-20 78 views
0

我有一個班,其中有2個人檢查餘額,並從普通賬戶中提取資金。我通過​​關鍵字使交易線程安全,但它有很多開銷,我已經閱讀了關於不可變對象和他們提供的線程安全。但我無法使這個類線程通過不變對象我可以通過不可變對象使這個類線程安全嗎?

代碼安全:

final class bank implements Runnable 
{ 
private final int balance,min_balance; 

bank(int bal,int mbal) 
{ 
    this.balance=bal; 
    this.min_balance=mbal; 
} 
@Override 
public void run() 
{ 
    transaction(); 

} 
public void transaction() 
{ 
    if(checkBalance()> min_balance) 
    { 
    System.out.println("checkin is done by : "+Thread.currentThread().getName() 
      +" and Balance left in the account is : "+checkBalance()); 
    System.out.println(Thread.currentThread().getName()+" is going to sleep ..."); 
    try{ 

     Thread.currentThread().sleep(2000); } 
     catch(Exception e){ 
     } 
    System.out.println(Thread.currentThread().getName()+" Woke up .."); 
    withdraw(); 
    System.out.println(Thread.currentThread().getName()+" has made the withdrawl .."); 
    } 
    else{ 
     lowBalance(); 
    } 
} 

int checkBalance() 
{ 
    return balance; 
} 
void lowBalance() 
{ 
    System.out.println("balance is not adequate"); 
} 

void withdraw() 
{ 
    balance=balance-20; //this wont work as balance is private 
} 

} 

public class ryanmonica { 

    public static void main(String args[]) 
    { 
    bank obj=new bank(100,20); 
    Thread t1=new Thread(obj); 
    Thread t2=new Thread(obj); 
    t1.setName("Ryan"); 
    t2.setName("Monica"); 
    t1.start(); 
    t2.start(); 

} 
} 

回答

1

不變對象的狀態不會改變。由於您的實例需要狀態更改(balanceminBalance正在更改),因此您需要使用同步機制。

不可變對象是線程安全的,因爲它們不允許在其實例中進行狀態更改。

+0

好的,我明白了你的意思..所以在線程安全中有任何實際使用的不可變對象嗎? – Amol

+0

@Amol不可變對象很有用,因爲您可以確保您所持有的對象始終具有相同的值,因此可以更好地推理程序。我不認爲不可變的數據可以提供多線程方面的神奇優勢,因爲如果你真的需要改變某些東西,你需要最終擁有一個對象來保存狀態,並且狀態必須是可變的。如果您需要充分利用不可變數據,系統函數式編程是一種更好的方法,這是另一個領域的問題。 – HuStmpHrrr

+0

@Amol - 是的。 C2 JIT編譯器將移除圍繞不可變實例的同步,因此JVM不會生成內存屏障的代碼,這將提高性能,因爲JVM可以將不可變對象傳遞給多個線程,而不必擔心一個線程對其他線程所做的更改。 – TheLostMind

相關問題