1

2 つのスレッドを並行して実行するアプリケーションがあり、それぞれが何らかのアクションを実行し、最終的に整数が生成されます。私のメインスレッドでは、各スレッド A とスレッド B によって生成された int に対して何らかの操作を実行し (それぞれ int a と int b と呼びます)、各スレッドがそれらを吐き出す順序で出力したいと思います。つまり、本質的に、私は各スレッドを定期的に (たとえば 2 秒ごとに) 実行しており、各スレッドは整数を吐き出し、それを操作して作成順に出力します。

これを行うには、GUI スレッドで印刷する必要がある各スレッドの int をどのように集計できますか? メインスレッドが監視するスレッドごとにキューを使用できますか?更新されると、メイン GUI がそれらを操作して出力しますか? どうすればそのようなキューを書くことができますか?

私のスレッドのコードは次のとおりです。

Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        new Thread(new t1()).start(//TODO: pass in some parameter that this
                                   //thread will write to); 
        new Thread(new t2()).start();
    }
}, 0, period);
4

3 に答える 3

1

このソリューションを検討してください。役立つ場合があります。ConcurrentLinkedQueueキューでのスレッドセーフな操作に使用します。

final Queue<Integer> queue1 = new ConcurrentLinkedQueue<Integer>();
final Queue<Integer> queue2 = new ConcurrentLinkedQueue<Integer>();

final Random r = new Random();

Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {             
    @Override
    public void run() {
        //Thread 1
        new Thread(new Runnable() {
            @Override
            public void run() {
                //even numbers
                queue1.add(r.nextInt(50)*2);
            }
        }).start();

        //Thread 2
        new Thread(new Runnable() {
            @Override
            public void run() {
                //odd numbers
                queue2.add(r.nextInt(50)*2 + 1);
            }
        }).start();
    }
}, 0, 2000);

//Main thread (maybe GUI)
while (true){
    while (!queue1.isEmpty()){
        System.out.println("Thread-1: " + queue1.poll());
    }
    while (!queue2.isEmpty()){
        System.out.println("Thread-2: " + queue2.poll());
    }
}

編集

本当に必要なのは Producer-Consumer です ( http://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problemを参照)。これを解決するには、別の queue を使用しますArrayBlockingQueue。このデータ構造により、何かが生成される (または消費される) までブロックできるからです。

final BlockingQueue<Integer> queue1 = new ArrayBlockingQueue<Integer>(1024);
final BlockingQueue<Integer> queue2 = new ArrayBlockingQueue<Integer>(1024);

final Random r = new Random();          

Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        try {
            //don't create threads here, this is already a thread, just produce the numbers
            //If the queue is full `BlockingQueue.put()` will block until the consumer consume numbers.

            //Producer even number
            queue1.put(r.nextInt(50)*2);

            //Producer odd number
            queue2.put(r.nextInt(50)*2 + 1);

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}, 0, 2000);

//Now we create the threads that will take numbers from the producer. Don't worry about the `while (true)`, it is not wasting resources because `BlockingQueue.take()` will block the thread until something is produced.

//Consumer 1
new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            while (true){
                System.out.println("Thread-1: " + queue1.take());

                //Or update some UI component
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}).start();

//Consumer 2
new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            while (true){
                System.out.println("Thread-2: " + queue2.take());

                //Or update some UI component
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}).start();
于 2013-10-02T05:19:17.367 に答える
1

Runnables の代わりにCallablesを使用するExecutorフレームワークを使用してみてください。Callable を使用する利点の 1 つは、 Runnableメソッドに類似したメソッドを提供することですが、メソッドは値にすることができます。したがって、あなたの場合、2 つのスレッドから整数値を返し、それらをメイン スレッドで使用できます。callruncallreturn

于 2013-10-02T04:52:54.547 に答える
0

両方のスレッドのコンストラクターにキューを渡します。

渡したキューの offer/add メソッドをオーバーライドし、ここで gui メイン スレッドを呼び出すロジックを追加します。基本的には、基本クラス呼び出しを呼び出した後にリスナーを呼び出します。

于 2013-10-02T04:58:36.653 に答える