考慮代碼:是否同步保持鎖定
class Account {
private int balance=50;
public int getBalance(){
return balance;
}
public void withdraw(int amt){
balance=balance-amt;
}
}
public class AccountBalance implements Runnable {
private Account acc=new Account();
public static void main(String[] args) {
AccountBalance accBal=new AccountBalance();
Thread one=new Thread(accBal);
Thread two=new Thread(accBal);
one.setName("Thread One");
two.setName("thread Two");
one.start();
two.start();
}
public void run(){
for(int i=0;i<5;i++){
makeWithdrawal(10);
}
}
public synchronized void makeWithdrawal(int amount){
if(acc.getBalance()>=amount){
System.out.println(Thread.currentThread().getName()+" is going to withdraw "+acc.getBalance());
try{
Thread.sleep(500);
}
catch(InterruptedException ie){}
acc.withdraw(amount); //line 1
System.out.println(Thread.currentThread().getName()+" completes the withdrawal");
}
else {
System.out.println("Not enough in account for "+Thread.currentThread().getName()+" to withdraw "+acc.getBalance());
}
}
}
1)假設主題弗雷德進入一個synchronized塊,並獲得對象鎖accBal然後在中間線程弗雷德呼叫另一種方法某處(第1行)這是不同步的,那麼線程不會釋放鎖定爲什麼?如果線程從synchronized同步出來,那麼它應該釋放鎖或者鎖直到synchronized塊。
2)假設我還有一個方法說changeAccount未然後同步的新線程說螺紋三其具有相同的對象accBal將進入該方法,並且可以改變可變平衡違反我們的同步代碼。
因此,即使存在非同步代碼並且線程在對象上有鎖,那麼另一個線程也不應該使用同一對象意味着一旦鎖定就進入非同步代碼已由Thread取得,除非釋放鎖,否則沒有Thread將作用於該對象。
CountDownLatch確實不提供互斥。事實上,它通常的用例基本上是相反的:它用來確保一組線程同時到達同一個點。 – 2014-11-25 14:39:16
我不建議使用CountDownLatch作爲提供互斥的方式,但我在說它可能會以不太好的方式用於這樣做。 – NESPowerGlove 2014-11-25 15:43:18