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

服务器处理一个小的数据库投掷文件(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'sleep和println以检测线程行为)。

在5秒结束之前,客户端2要求服务器将(或任何其他方法)student2添加到univ2。

正如client2要求在univ2上添加一个内容一样,我希望锁定会占用univ2,因此线程不会等待,因为univ2不像univ1那样被锁定。

谁能帮我理解?

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

谢谢。

最佳答案

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


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

如果您遵循建议的做法将普通的Object用作锁,则可以避免这种情况。

我还应该评论一下,您的整个设计都是不必要的回旋:由于fac在实例化时是固定的,因此最好在此时为实例变量分配适当的锁对象,而不是在每次方法调用时都要经过决策级联。

07-24 19:40