繁体   English   中英

线程没有通信

[英]Threads not communicating

我正在制作一个程序,其中x个线程池与共享库存交互。 在这种情况下,我使用ArrayList作为共享库存。 在我的程序中,线程是生物具有的作业的表示。 生物属于一方并共享用于执行工作的工件池。 只有一个生物我随时与游泳池互动。

出于某种原因,我一直遇到线程通信问题。 我已经设置了它,所以如果没有使用游泳池,该生物会将所有物品放入游泳池并开始查看它。 如果他们找不到他们需要的所有东西,他们应该将他们拥有的所有工件放入池中,将池设置为不忙,然后发信号通知一个等待池的生物,它已准备好让它们通过它。

我的问题是,如果一个生物正在通过水池观察而另一个正在等待,并且它无法找到它想要的东西,它会重复该过程而不会通知或让其他生物通过它。

我尝试过的:我最初尝试使用锁,但锁不会发出其他线程的信号。 然后我利用synchronized(Party)重写了它。 然后我认为这是因为线程在某个地方崩溃,但线程可以一直运行,甚至在作业完成时将其项目转回到池中(假设生物没有将池锁定到空中)。

boolean ready = target.hasReqArtifacts( reqStones, reqPotions, reqWands, reqWeapons );
    //checks to see if creature already has correct amount of each item.
    //If it does it should skip pool interaction until it dumps its used items
    //back into the pool.
    System.out.println( "Ready: " + ready );
    while ( !ready ) {//begin pool interaction
        synchronized ( target.poolParty ){
            System.out.println( "Ready: " + ready );
            System.out.println( this );
            while ( target.poolParty.busyPool ) {//busyPool is initialized false
                startJob.setEnabled( false );
                try {
                    target.poolParty.wait();
                } catch ( InterruptedException e ) {}
            }
            synchronized ( target.poolParty ) {
                target.poolParty.busyPool = true;
                target.poolParty.notifyAll();//notify all threads that they need to wait because this one will proceed
            }
        }
        target.releaseArtifacts();// adds all artifacts held by creature to an arraylist in poolParty
                                  //then clears the creatures inventory
        target.pickUpArtifacts( reqStones, reqPotions, reqWands, reqWeapons );

        ready = target.hasReqArtifacts( reqStones, reqPotions, reqWands, reqWeapons );
        if ( ready ) {
            synchronized ( target.poolParty ) {
                System.out.println( "has required Items" );
                target.poolParty.busyPool = false;
                target.poolParty.notify();
            }
        } else {
            synchronized ( target.poolParty ) {
                System.out.println( "Does not has required Items" );
                target.poolParty.busyPool = false;
                target.releaseArtifacts();
                target.poolParty.notifyAll();
                try {
                    Thread.sleep( 1000 );
                } catch ( InterruptedException e ){}
            }
        }
    }//end pool interaction

我在线程中执行这种交互,在一个场景中,一个生物有一个以上的工作,但一次只能做一个工作而且它完美地工作。 我根据这种情况量身定制了这些方法,但我仍然遇到问题。

注意:我对并发很新,所以请原谅我,如果我的词汇不是在这个主题上发展的话。

看起来你正在使用target.poolParty进行同步的块中睡觉。 这意味着等待访问池的其他线程将无法访问它,因为该线程正在阻止它。 sleep()移到该块之外。

在另一个地方,您在已经使用synchronized进行同步的块中使用synchronized (target.poolParty) 这是不必要的(好吧,整个代码块是不必要的,我删除它。只是指出)。 wait()notify*()也是低级同步原语,很少需要。

boolean ready = target.hasReqArtifacts( reqStones, reqPotions, reqWands, reqWeapons );
//checks to see if creature already has correct amount of each item.
//If it does it should skip pool interaction until it dumps its used items
//back into the pool.
System.out.println( "Ready: " + ready );
while ( !ready ) {
    // begin pool interaction
    synchronized (target.poolParty) {
        target.pickUpArtifacts( reqStones, reqPotions, reqWands, reqWeapons );
        ready = target.hasReqArtifacts( reqStones, reqPotions, reqWands, reqWeapons );

        /* I'd move this here. If we never release out items then the
           other party members can't use them while this one still does
           not have the needed items. Now they will be available to
           other parties while this thread sleeps. */
        if (!ready) {
            // adds all artifacts held by creature to an arraylist in poolParty
            target.releaseArtifacts();
        }
    }

    // These don't access the pool, so they can be outside the synchronized block
    if ( ready ) {
        System.out.println( "has required Items" );
    } else {
        System.out.println( "Does not have required Items" );
        // Sleep before the next try to get the required items. Lets other
        // threads attempt to fetch their needed items
        try {
            Thread.sleep( 1000 );
        } catch ( InterruptedException e ) {
            // Added, because silently eating exceptions is a bad idea
            e.printStackTrace();
        }
    }
}//end pool interaction

看起来你在想这个问题。 您的用例很简单。

  • 在任何给定时间,只有一个生物应该能够访问该池。
  • 其他生物必须在此期间等待。
  • 这里的共享资源是池。

现在很简单

synchronize(pool){
//doStuff
}

应该管用。

请注意,当您需要同步不完全属于单个连续逻辑块的不同代码部分时,需要wait()notify()/notifyAll()

boolean ready = target.hasReqArtifacts( reqStones, reqPotions, reqWands, reqWeapons );
//checks to see if creature already has correct amount of each item.
//If it does it should skip pool interaction until it dumps its used items
//back into the pool.
System.out.println( "Ready: " + ready );
if ( !ready ) {//begin pool interaction
    synchronized ( target.poolParty ){
        System.out.println( "Ready: " + ready );
        System.out.println( this );
        startJob.setEnabled( false );
    }
    target.releaseArtifacts();// adds all artifacts held by creature to an arraylist in poolParty
                              //then clears the creatures inventory
    target.pickUpArtifacts( reqStones, reqPotions, reqWands, reqWeapons );
    }
}//end pool interaction

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM