如何在Java中最好地同步访问一个类的两个线程
我有一个发送SNMP命令和监听陷阱的程序 我的第一个方法协调SNMP的发送。一旦他完成发送,我需要他等待,直到他收到一个通知,陷阱已经收到,所以他可以继续运行。现在,我正试图通过同步一个全局对象来实现这一点,但它不起作用,我也不确定它是否是适合我的理想解决方案如何在Java中最好地同步访问一个类的两个线程,java,multithreading,synchronization,Java,Multithreading,Synchronization,我有一个发送SNMP命令和监听陷阱的程序 我的第一个方法协调SNMP的发送。一旦他完成发送,我需要他等待,直到他收到一个通知,陷阱已经收到,所以他可以继续运行。现在,我正试图通过同步一个全局对象来实现这一点,但它不起作用,我也不确定它是否是适合我的理想解决方案 public synchronized int loginUser(ScopedPDU pdu) throws IOException { loginUserManager = new LoginUserManager();
public synchronized int loginUser(ScopedPDU pdu) throws IOException
{
loginUserManager = new LoginUserManager();
pdu = buildPdu();
// send command
errorStatus = snmpManager.snmpSend(pdu);
if (errorStatus == SnmpManager.SNMP_PASS)
{
// Wait for traps
synchronized(syncObject)
{
// read global variable status to see if it's no longer in progress
while(status == TrapStatus.INPROGRESS)
{
try {
System.out.println("Waiting for login to be done");
syncObject.wait();
System.out.println("We received a notify");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} //(errorStatus == SnmpManager.SNMP_PASS)
else
{
return TrapStatus.FAIL;
}
System.out.println("Returning status");
return status;
}
我的第二个方法是接收一个陷阱(并在第一个方法运行的另一个线程上运行)并获得我想要的正确状态,但我无法通知另一个线程
public synchronized void readTrap(Vector v)
{
Enumeration e = v.elements();
if(v.contains(PduTrap.UserLoginStatusTrap))
{
// gets status of login
status = loginUserManager.getStatus(e);
synchronized(syncObject)
{
// notify first method to read the new status
syncObject.notify();
}
}
}
status和SyncObject是我试图在线程之间共享的全局类型。我在类构造函数中将状态初始化为INPROGRESS
private int status;
private Object syncObject;
有人能告诉我为什么事情不管用,或者我是不是完全走错了方向?目前,readTrap没有通知我的loginUser方法。谢谢你 你可以考虑共享<代码>阻塞队列< /> >,所以<代码>读陷阱(…)>代码>方法将<队列>(代码)>(可能是新的状态)和<代码> Login用户(…)<代码> >从队列中<代码>收件人> /代码>。这将负责所有的锁定和信令,而无需执行等待/通知 在调试代码时,您需要确保
syncObject
是private final
对象,以便wait和notify共享相同的对象引用。显然,如果它们是从不同的对象工作的,那么您的代码将无法工作
此外,还应在
synchronized
块内设置状态。我不确定它在这里有什么不同,但对代码至关重要的任何值都应该在互斥块中。你可以考虑在两种方法中打印状态值,以确保它像你所想的那样被更新。 < P>这不是唯一做这种事情的方式,但是人们通常认为这种流程是解决方案。(我希望这不是那么抽象,没有意义。)
--方法1--
可能SNMP命令有一个顺序,您必须依次执行一个命令和另一个命令。第一种方法很好地实现了这一点,因为您可以按顺序进行调用。第二种方法使这一点更加困难,因为B部分的异步完成必须查找,然后启动序列中的下一项。这就变得复杂了。请将您的syncObject对象作为最终对象(私有对象syncObject=new Object(););请注意,同步块使用对象引用;因此,如果对象引用发生更改,您将无法看到所需的行为
另外,请从这两个函数中删除synchronized,为什么需要它?如果两个线程在同一对象上工作;这可能会引起问题。请注意,同步方法使用此引用进行同步 阻塞队列看起来很容易使用,对我来说可能是一个更好的解决方案。我来试试看,谢谢!