Java RMI-线程的意外行为

时间:2013-12-22 15:39:03

标签: java multithreading synchronization rmi

我是java rmi的新手,我遇到同步问题。

服务器处理一个小的数据库throw文件(7个文件,每个文件代表一个大学),

客户端在连接时会给出大学的名称,然后选择一个选项:

  • 添加学生

  • 删除学生

  • 更新学生

  • 搜索学生

一切正常,但我遇到同步问题。它没有按我预期的方式工作。

假设我们有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。

当client2在univ2上添加一个add时,我预计锁会占用univ2所以线程不会等待,因为univ2没有锁定,与univ1不同。

任何人都可以帮助我理解吗?

任何有关获得预期行为的建议都会受到欢迎。

感谢。

1 个答案:

答案 0 :(得分:3)

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

这是对同一个对象的三个引用,该类的内部缓存中的Integer实例的所有值介于-128和128之间。

如果按照建议的惯例使用普通Object来锁定,你就可以避免这种情况。

我还应该评论你的整个设计是不必要的回合:因为fac在实例化时被修复,你最好在那个时候将正确的锁对象分配给实例变量而不是通过决定在每个方法调用上级联。