下面是我的精简版java代码供审阅。我有几个子类,当调用execParallel()时,会启动一个新线程。该线程和默认线程必须通过actionFunction()多次执行criticalFunction(),但是如果一次仅由一个进程执行,则此函数仅对给定的SubClassC连接正常工作。
我使用了关键字“synchronized”来防止并发执行,但实际上,criticalFunction()实际上是由两个线程同时调用的。
知道我做错了什么吗?
public class MainClass extends GlobalLibrary {
public static SubClassA masterObj;
public MainClass() {
masterObj = new SubClassA();
}
public static class SubClassA {
public SubClassB subObj1;
public SubClassB subObj2;
public SubClassA() {
subObj1 = new SubClassB();
subObj2 = new SubClassB();
}
}
public static class SubClassB {
public SubClassC conObj;
public Thread ut = null;
public SubClassB() {
conObj = new SubClassC();
}
}
public static class SubClassC {
public TCPMasterConnection con=null;
public SubClassC() {
con = new TCPMasterConnection();
}
public synchronized Object criticalFunction(int arg) {
return otherClass.executeCritical(con, arg);
}
}
public boolean actionFunction(SubClassB subObj, int arg) {
return (subObj.conObj.criticalFunction(arg)==null);
}
public class ActionThread implements Runnable {
public SubClassB subObj;
private int icode;
public ActionThread(SubClassB arg1, int arg2) {
subObj = arg1;
icode = arg2;
}
public void run() {
for (int i=0; i<10; i++) actionFunction(subObj, icode);
}
}
public void execParallel() {
masterObj.subObj1.ut = new Thread(new ActionThread(masterObj.subObj1, 1));
masterObj.subObj1.ut.start();
actionFunction(masterObj.subObj1, 2);
actionFunction(masterObj.subObj1, 3);
actionFunction(masterObj.subObj1, 4);
actionFunction(masterObj.subObj1, 5);
actionFunction(masterObj.subObj1, 6);
}
}
答案 0 :(得分:1)
如果您的目标是保护otherClass.executeCritical(con, arg)
调用,那么您需要锁定otherClass
实例的粒度。如果目标是在给定时间只有一个线程使用“主连接”,这似乎是您非常想要的,那么您需要锁定粒度在TCPMasterConnection
的实例。在后一种情况下,您的代码将如下所示:
public Object criticalFunction(int arg) {
synchronized(con) {
return otherClass.executeCritical(con, arg);
}
}
现在,如果在otherClass
和con
(TCPMasterConnection)中都有多线程不安全的代码,那么您可能希望锁定具有更大的粒度。在这种情况下,一个简单的事情可能是锁定在类级别,如其他答案所述。
答案 1 :(得分:0)
是否要部分代码要进行同步,请改为:
Object lock = new Object();
public void doSomething{
synchronized(lock){
//your code
}
}
Synchronized methods
仅适用于实例级。
答案 2 :(得分:0)
您在不同的实例上调用criticalFunction(),因此它们使用不同的锁。您需要在所有实例之间共享锁定。
试试这个
public Object criticalFunction(int arg) {
synchronized (SubClassC.class) {
return otherClass.executeCritical(con, arg);
}
}