线程不通讯

137

我正在编写一个程序,其中x个线程的池与共享清单进行交互。在这种情况下,我使用ArrayList作为共享清单。在我的程序中,线程表示生物所从事的工作。生物属于一个聚会,并且共享用于执行工作的人工制品池。我只有一个生物随时与泳池互动。

由于某种原因,我一直在线程通信方面遇到问题。我已经设置好了,所以如果不使用游泳池,该生物会将其所有物品掉入游泳池并开始查看。如果他们找不到所需的一切物品,则应将其拥有的所有文物放入池中,将池设置为不繁忙,然后向等待池中的一个生物发出信号,告知他们也准备好通过该池。

我的问题是,如果一个生物在等待另一个生物的同时正在池中寻找,并且找不到通知或不让另一个生物通过它,它将无法找到重复的过程。

我尝试过的事情:我最初尝试使用锁,但是这些锁不会向其他线程发出信号。然后我利用同步(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 (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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章