0

我有一个发送 SNMP 命令并侦听陷阱的程序。

我的第一种方法是协调 SNMP 的发送。一旦他完成发送,我需要他等到他收到陷阱已收到的通知,这样他才能继续运行。现在,我正在尝试通过同步一个全局对象来做到这一点,但它不起作用,我不确定它是否是我的理想解决方案。

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;  

有人可以告诉我为什么事情不正常,或者我是否完全以错误的方式解决这个问题?目前,我的 loginUser 方法没有被 readTrap 通知。谢谢

4

3 回答 3

0

Please make your syncObject Object, as final (private Object syncObject = new Object();); please note that synchronized block uses the Object reference; so in case if the Object reference get changed, you will not see the needed behavior.

Also, please remove synchronized from both the function, why you need it? If both the thread are working on same Object; it may cause issue. Please note that synchronized method use this reference for synchronization.

于 2013-02-01T19:39:26.583 回答
0

您可能会考虑共享BlockingQueue,因此该readTrap(...)方法将add()进入队列(也许是新状态?)并且loginUser(...)来自take()队列。这会处理所有锁定和信号,而无需您进行等待/通知。

在调试代码方面,您需要确保syncObject是一个对象,以便等待和通知共享private final相同的对象引用。显然,如果他们使用不同的对象工作,那么您的代码将无法工作。

此外,您应该在块内设置状态。synchronized我不确定它在这里有什么不同,但是对代码至关重要的任何值都应该在互斥块中。您可以考虑在这两种方法中打印 status 的值,以确保它按照您的想法进行更新。

于 2013-02-01T19:19:03.403 回答
0

这不是做这类事情的唯一方法,但人们通常认为这种流程是解决方案。(我希望这不是太抽象以至于没有意义。)

--方法一--

  1. 做某事的一部分
  2. 发出其他信号以异步执行某些工作
  3. 在某些结果发生之前什么都不做
  4. 完成你开始的事情
  5. 将完成状态返回给其他代码。

可以通过这种方式完成,但通常比将其分成两组步骤的另一种方式要困难得多。

--方法二--

A部分

  1. 做某事的一部分
  2. 保存正在进行的工作
  3. 发出其他信号以异步执行某些工作
  4. 忘掉它

B部分

  1. 得到通知,另一件事已完成。
  2. 检索正在进行的工作
  3. 做剩下的工作
  4. 全部完成

注意一个关键的区别是,第一种方式,你实际上有结果状态,你可以返回到调用这些东西的代码。第二种方式,这两个部分不再同步,你不能这样做。

你想要做什么取决于调用者需要什么。

也许有一个需要执行的 SNMP 命令列表。如果是这样,您只需要B 部分在完成或标记失败时将事情从列表中标记出来,以便其他人可以重试或通知某些人。

也许对 SNMP 命令有一个排序,您必须按顺序执行一个,然后执行另一个。第一种方法适用于此,因为您可以按顺序进行调用。第二种方法更难,因为B 部分的异步完成将不得不查找然后启动序列中的下一个项目。这变得很复杂。

于 2013-02-01T19:32:35.337 回答