线程没有通信

时间:2013-07-27 11:25:32

标签: java concurrency sync

我正在创建一个程序,其中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

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

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

2 个答案:

答案 0 :(得分:1)

看起来您正在使用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 是低级同步原语,很少需要。

{{1}}

答案 1 :(得分:1)

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

  
      
  • 任何时候只有一个生物能够进入游泳池。
  •   
  • 其他生物必须在此期间等待。
  •   
  • 这里的共享资源就是游泳池。
  •   

现在很简单

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