簡體   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