如果您有一些主线程必须从其他线程接收事件(很像服务器套接字),那么一些阻塞队列可能是一种解决方案。主线程可以takeLast
在循环中调用 - 这将暂停它,直到任何其他线程调用putFirst
,为同一队列提供一个值。(SynchronousQueue将停止提供线程,直到主线程准备好,或者ArrayBlockingQueue支持给定大小的队列)。
通过这样的设置,主线程也不能是 GUI 线程。如果您需要从中触摸标签或按钮等界面组件,请使用invokeAndWait 。
final BlockingQueue q = new ArrayBlockingQueue(3);
new Thread() {
public void run() {
while (have_some_messages()) {
q.putFirst("Hey!");
}
}
}.start();
new Thread() {
public void run() {
while (also_have_some_messages()) {
q.putFirst("Boo!");
}
}
}.start();
// Main thread will print both Hey and Boo:
while (must_keep_running()) {
Object serveIt = q.takeLast();
System.out.println(serveIt);
}
如果主线程是 Swing 线程(您说带有 Swing 控件的 JFrame),请在此处添加一个按钮以启动服务线程:
Runnable service = new Runnable() {
public void run() {
try {
while (must_keep_running()) {
Object serveIt = q.takeLast();
System.out.println(serveIt);
}
} finally {
// Re-enable the start button when the service thread exits:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
bStart.setEnabled(true);
}
});
};
}
};
JButton bStart = new JButton("Start ..");
bStart.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new Thread(service).start();
bStart.setEnabled(false);
}
}
});