2013-12-22 48 views
1

我是java rmi的新手,我遇到同步問題。Java RMI-線程的意外行爲

服務器處理一個小數據的基礎上擲文件(7個文件,每一個代表一個大學),

連接,當客戶端給出大學的名稱,然後選擇一個選項:

  • 添加學生

  • 刪除學生

  • 更新學生

  • 搜索學生

一切工作正常,但我有synchronization.It一個問題不工作,我所期望的方式。

假設我們有3個文件,我創建了3個私人靜態整數使用這樣

public class CarnetImpl extends UnicastRemoteObject implements Carnet { 

    private String fac; 
    private static Integer univ1=1; 
    private static Integer univ2=1; 
    private static Integer univ3=1; 

    CarnetImpl(String fac) throws RemoteException { 
     this.fac=fac; 
    } 
    public void add(Student e) throws RemoteException { 
     Integer lock=1 
     switch (fac){ 
      case "univ1": 
      lock=univ1; 
      break; 

      case "univ2": 
      lock=univ2; 
      break; 

      case "univ3": 
      lock=univ3; 
      break; 
     } 
     synchronized(lock){ 
      //creating a file named "fac.txt" (fac can be univ1,2 or3) and adding a student 
     } 
    } 
} 

我做了其他方法同樣的事情。

我期望是什麼,對於一個給定的大學只有一個客戶端可以使用的方法,而超過一個客戶端可以同時使用不同的大學同樣的方法。

但經過測試看來,甚至是不同的高校客戶端必須等待其他完成使用的方法。

實施例:

客戶機1請求服務器student1添加到univ1(ⅰ加入5' 睡眠和一個println檢測線程行爲)。

的5秒客戶機2結束之前要求服務器添加(或任何其它方法)到STUDENT2 univ2。

由於客戶機程序要求上univ2的添加,我預計鎖將採取univ2所以線程不會等待,因爲univ2是沒有什麼不同univ1鎖定。

任何人都可以幫助我理解嗎?

任何建議,以獲得預期的行爲將是最受歡迎的。

謝謝。

回答

3
private static Integer univ1=1; 
private static Integer univ2=1; 
private static Integer univ3=1; 

這些都是三個引用到同一個對象,從-128到128之間的類的所有值的內部緩存的Integer實例

你本來可以避免這一點,如果你一直到推薦使用普通Object作爲鎖。

我也應該評論說,你的整個設計是不必要的迂迴:因爲fac固定在實例化時間,你最好將正確的鎖定對象分配給實例變量,而不是通過每個實例變量方法調用。