我是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
在实例化时是固定的,因此最好在此时为实例变量分配适当的锁对象,而不是在每次方法调用时都要经过决策级联。