Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中最好地同步访问一个类的两个线程_Java_Multithreading_Synchronization - Fatal编程技术网

如何在Java中最好地同步访问一个类的两个线程

如何在Java中最好地同步访问一个类的两个线程,java,multithreading,synchronization,Java,Multithreading,Synchronization,我有一个发送SNMP命令和监听陷阱的程序 我的第一个方法协调SNMP的发送。一旦他完成发送,我需要他等待,直到他收到一个通知,陷阱已经收到,所以他可以继续运行。现在,我正试图通过同步一个全局对象来实现这一点,但它不起作用,我也不确定它是否是适合我的理想解决方案 public synchronized int loginUser(ScopedPDU pdu) throws IOException { loginUserManager = new LoginUserManager();

我有一个发送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;  

有人能告诉我为什么事情不管用,或者我是不是完全走错了方向?目前,readTrap没有通知我的loginUser方法。谢谢你

你可以考虑共享<代码>阻塞队列< /> >,所以<代码>读陷阱(…)>代码>方法将<队列>(代码)>(可能是新的状态)和<代码> Login用户(…)<代码> >从队列中<代码>收件人> /代码>。这将负责所有的锁定和信令,而无需执行等待/通知

在调试代码时,您需要确保
syncObject
private final
对象,以便wait和notify共享相同的对象引用。显然,如果它们是从不同的对象工作的,那么您的代码将无法工作


此外,还应在
synchronized
块内设置状态。我不确定它在这里有什么不同,但对代码至关重要的任何值都应该在互斥块中。你可以考虑在两种方法中打印状态值,以确保它像你所想的那样被更新。

< P>这不是唯一做这种事情的方式,但是人们通常认为这种流程是解决方案。(我希望这不是那么抽象,没有意义。)

--方法1--

  • 做某事的一部分
  • 向其他对象发送信号以异步执行某些工作
  • 除非有结果,否则什么都不要做
  • 完成你开始做的事
  • 将完成状态返回到其他代码
  • 可以这样做,但通常比将其分为两组步骤的另一种方法要困难得多

    --方法2--

    A部分

  • 做某事的一部分
  • 保存正在进行的工作
  • 向其他对象发送信号以异步执行某些工作
  • 算了吧
  • 乙部

  • 得到另一件事已经完成的通知
  • 检索正在进行的工作
  • 做剩下的工作
  • 全部完成
  • 请注意,一个关键的区别是,第一种方式,您实际上拥有结果状态,您可以返回到调用这些内容的代码。第二种方法是,这两个部分不再同步,您不能这样做

    你想做什么取决于打电话的人需要什么

    可能存在需要执行的SNMP命令列表。如果是这样的话,您所需要做的就是让Part B在完成任务时将事情从列表中标记出来,或者标记失败,以便其他人可以重试或通知某些人


    可能SNMP命令有一个顺序,您必须依次执行一个命令和另一个命令。第一种方法很好地实现了这一点,因为您可以按顺序进行调用。第二种方法使这一点更加困难,因为B部分的异步完成必须查找,然后启动序列中的下一项。这就变得复杂了。

    请将您的syncObject对象作为最终对象(私有对象syncObject=new Object(););请注意,同步块使用对象引用;因此,如果对象引用发生更改,您将无法看到所需的行为


    另外,请从这两个函数中删除synchronized,为什么需要它?如果两个线程在同一对象上工作;这可能会引起问题。请注意,同步方法使用此引用进行同步

    阻塞队列看起来很容易使用,对我来说可能是一个更好的解决方案。我来试试看,谢谢!