1

コードを見ると、2 つの ArrayLists が呼び出され、押され、解放されてグローバルになっています。私がしなければならないことは、押されるキーでこれらの配列を更新し、これらの更新された配列をスレッドに渡すか、スレッドを更新することです..これは、私がしなければならないことについて少し迷っている部分です. .

現在の例(実行するかどうかはテストされていません)は、実際のプログラムで使用したものの基本的な例です。実行すると、ボタンを1回押すと、スローしてエラーが発生しました。今はテストできないため、エラーを思い出せませんが、スレッドの使用方法に関係していました。

質問 スレッドが開始されたら、配列をスレッドに渡すにはどうすればよいですか。

コード例:

import oscP5.OscEventListener;
import oscP5.OscMessage;
import oscP5.OscP5;
import oscP5.OscStatus;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Main implements OscEventListener {

protected BlockingQueue<Integer> _KeyQue = new ArrayBlockingQueue<>(1024);

Producer producer = new Producer(this._KeyQue);
Consumer consumer = new Consumer(this._KeyQue);
ThreadTest threadTest = new ThreadTest(this._KeyQue);

Thread prod;
Thread con;
Thread threadT;

OscP5 osc = new OscP5(this, 22556);

public static void main(String[] argv) {
    Main main = new Main();
    main.setup();
}

public void setup() {
    prod = new Thread(producer);
    con = new Thread(consumer);
    threadT = new Thread(threadTest);

    prod.start();
    con.start();
    threadT.start();

}

@Override
public void oscEvent(OscMessage theMessage) {
    float val = Float.parseFloat(theMessage.arguments()[0].toString());

    if (val == 1.0) {
        producer.addKey(KeyEvent.VK_W);
        producer.addKey(KeyEvent.VK_S);
    } else {
        consumer.removeKey(KeyEvent.VK_S);
    }
   threadTest.run();
}

@Override
public void oscStatus(OscStatus theStatus) {}

public class Producer implements Runnable {
    protected BlockingQueue<Integer> _KeyQue = null;

    public void addKey(int key) {
        try {
            this._KeyQue.put(key);
            System.out.println("Key " + key +" added to queue");
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
    }

    public Producer(BlockingQueue<Integer> _KeyQue) {
        this._KeyQue = _KeyQue;
    }

    public void run() {

    }
}

public class Consumer implements Runnable {
    protected BlockingQueue<Integer> _KeyQue = null;

    public void removeKey(int key) {
        try {
            this._KeyQue.remove(key);
            System.out.println("key " + key + " removed from queue");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    public Consumer(BlockingQueue<Integer> _KeyQue) {
        this._KeyQue = _KeyQue;
    }

    public void run() {

    }
}

public class ThreadTest implements Runnable {

    protected BlockingQueue<Integer> _KeyQue = null;

    public ThreadTest(BlockingQueue<Integer> _KeyQue) {
        this._KeyQue = _KeyQue;
    }

    public void run() {
        try {
            Robot robot = new Robot();

            while(!this._KeyQue.isEmpty()) {
                for (Integer x : this._KeyQue) {
                    System.out.println("Keys in que: " + x);
                    Thread.sleep(500);
                }
            }

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}
}

編集: わかりましたので、スレッドと BlockingQueue を調べましたが、まだ理解できない、プログラムをロックせずにThreadTest の run()メソッドを実行し続ける方法です。この例では、まったく実行されません。threadTest.run()を直接呼び出すと、その中のプログラムがロックされ、要素の追加または削除が許可されません。

したがって、私がする必要があるのは、常に実行されているスレッドをバックグラウンドで実行し、*_KeysQueue()*をループして、この例ではキーに関連付けられた番号を出力できるようにすることです。これはすべて、キーの追加と削除を許可している間に発生するはずです。

4

3 に答える 3

0

および メソッドを使用してBlockingQueue、他のすべてのスレッドから呼び出される要素を追加できます。addKey他のすべてのスレッドからアクセスでき、新しいキーをBlockingQueue.

そこではプロデューサー/コンシューマー パターンを使用できます。『Java Concurrency In Practice』という本、またはこの本にたどり着いたリンクをブログThe Java Specialistsで見ることができます。この本には、すべてのキュー、同時または同期リスト、いくつかのことを実行するコードの実装方法の例があり、何かについて 50 ページを読むために立ち止まる必要はありません。すべての問題の例といくつかの段落。

于 2013-01-12T18:27:27.530 に答える
0

ArrayListスレッドセーフではないため、このように使用しないでください: 機能するか、失敗する可能性があります。

さらに、無駄にリソースを消費するビジー待機の代わりに、ある種の同期メカニズムを使用する必要があります。

したがって、スレッド間の単純なデータ受け渡しメカニズムを提供するBlockingQueueコレクションを見てください。

于 2013-01-12T18:18:12.883 に答える
0

クラスにセッターメソッドを用意する

public class ThreadTest implements Runnable {
    ....
    public void setPressedList(ArrayList<Integer> e) {
       this.pressed = e;
    }
    public void setReleasedList(ArrayList<Integer> f)
    {
       this.released = f
    }
}
于 2013-01-12T18:06:09.550 に答える