0

スレッドを使用する Java プログラムを作成しようとしています。プログラムの開始時に 3 つのスレッドを実行し、それらを「作業指示書」の ArrayList で待機させたいと考えています。最初は、作業指示はありません。したがって、スレッドはただ待つ必要があります。将来のある時点で、作業命令が ArrayList に追加される予定であり、メイン スレッドは実行すべき作業があることをスレッドに通知する必要があります。

(Runnableを実装する代わりに)Threadを拡張することでそれを実現したいと考えています。

私が抱えている主な問題は、スレッドがworkorders ArrayListと正しく同期されていないことだと思います。

私のコードは次のようになります。

  public static void main(String[] args) {

    AnotherRunnable anotherRunnable = new AnotherRunnable();
    ArrayList<ATMRunnable> workOrders = new ArrayList<ATMRunnable>();

    T1 t1 = new T1(anotherRunnable, workOrders);
    T1 t2 = new T1(anotherRunnable, workOrders);

    t1.start();
    t2.start();

    try{
        Thread.sleep(2000);
    }
    catch(InterruptedException e){}

        synchronized (workOrders){

        System.out.println(t1.getState() + " - " + t1.getName());
        System.out.println(t2.getState() + " - " + t2.getName());

        System.out.println("notify");
        workOrders.notify();

        System.out.println(t1.getState() + " - " + t1.getName());
        System.out.println(t2.getState() + " - " + t2.getName());

    }
  }

AnotherRunnable クラス:

public class AnotherRunnable implements Runnable {

public void run()
{
    System.out.println("AnotherRunnable");

}
}

そしてトレッドクラス:

public class T1 extends Thread {

 AnotherRunnable anotherRunnable;
ArrayList<ATMRunnable> workOrders;

ATMThread(AnotherRunnable anotherRunnable, ArrayList<ATMRunnable> workOrders)
{
    this.anotherRunnable = anotherRunnable;
    this.workOrders = workOrders;
}

public void run()
{
    System.out.println("Run Thread");

    synchronized (workOrders){
        try{
            System.out.println("wait Thread");
            workOrders.wait();
        }
        catch (InterruptedException e){}
    }

}

}

これはプログラムの出力です:

Run Thread
wait Thread
Run Thread
wait Thread
WAITING - Thread-1
WAITING - Thread-2
notify all
BLOCKED - Thread-1
WAITING - Thread-2

ご覧のとおり、最初のスレッドの状態は、workOrders オブジェクトでの通知の呼び出しの後、Blocked に変更されます。ただし、スレッドも実行可能なオブジェクトも実行されません。

どんな助けでも大歓迎です。

4

2 に答える 2

0

手動による同期をできる限り回避するために、Java で並行コレクションを使用する必要があります。

プログラムの開始時に 3 つのスレッドを実行し、それらを「作業指示書」の ArrayList で待機させたいと考えています。最初は、作業指示はありません。したがって、スレッドはただ待つ必要があります。将来のある時点で、作業命令が ArrayList に追加される予定であり、メイン スレッドは実行すべき作業があることをスレッドに通知する必要があります。

この種の同期では、ブロッキング キューはLinkedBlockingQueueのような友達であり、キューにアイテムがない場合やキューがいっぱいの場合にスレッドを待機させます。そこに同期/待機/通知は必要ありません。

それが役立つかどうかも確認できます:同期は危険です

学習目的のみの場合は、最初に同期を論理的に適切にする必要があります。問題のある待機または通知の条件を使用しません。適切であれば機能しますが、推奨される方法ではありません。

于 2013-05-12T19:11:32.213 に答える
0

これを機能させるために何をしなければならないかを見つけました。主に欠けていたのはコンセプトでした。スレッドの run メソッドでループする必要がありました。notifyall が呼び出されるたびにそのメソッドが呼び出されると考えていましたが、これは正しくありません。同期されたオブジェクトで wait() が呼び出されると、スレッドが停止し、通知により実行が再開されます。そのコードがループ内にない場合、スレッドは実行されません。

于 2013-05-13T17:52:57.253 に答える