考虑这个解决方案,您可能会发现它很有用。它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());
}
}
编辑
您真正需要的是生产者-消费者(参见http://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem)。为了解决这个问题,我们将使用另一个队列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();