如果查看代码,我有两个全局调用,压缩和释放的ArrayLists。我要做的是用要按下的键更新那些数组,然后将这些更新的数组传递给我的线程,或更新线程..这是我不知所措的部分。
当前示例(未经测试,如果运行),是我在实际程序中的基本示例。当我运行它时,它会按下按钮一次,然后它会抛出错误,我不记得错误,因为我现在无法测试它,但它与我使用线程的方式有关。
的问题 的 一旦线程启动,我如何将数组传递给我的线程。
代码示例:
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()* ,在本例中,打印输出与之关联的数字键。这应该在允许我添加和删除键的同时发生。
答案 0 :(得分:0)
在班级中设置一个setter方法
public class ThreadTest implements Runnable {
....
public void setPressedList(ArrayList<Integer> e) {
this.pressed = e;
}
public void setReleasedList(ArrayList<Integer> f)
{
this.released = f
}
}
答案 1 :(得分:0)
ArrayList 不是线程安全的,所以你不应该这样使用它们:它可以工作或者它可能会失败。
此外,您应该使用某种同步机制,而不是忙等待,这会消耗资源。
那么看一下 BlockingQueue 集合,它将为您提供线程之间的简单数据传递机制。
答案 2 :(得分:0)
您可以使用BlockingQueue
和方法添加将从其他每个线程调用的元素。您可以使用静态方法addKey
,该方法可以从其他每个线程访问,并且可以将新密钥添加到BlockingQueue
。
您可以在那里使用the producer-consumer pattern,您可以在博客Java Concurrency In Practice中看到图书The Java Specialists或引导我阅读该书的链接。本书包含所有队列,并发或同步列表的示例,实现代码以执行多项操作的方法,以及所有这些都无需停止阅读50页的内容。每个问题的一个例子和几个段落。