我试图找出如何消除Java中的线程中的繁忙循环。该线程只会等待Listener类的回调。线程类看起来像这样:
class MyThread implements Runnable, MessageListener{
private Listen Listener;
public MyThread(){
Listener = new Listener(this);
}
public void run(){
while(true){}
}
public void messageReceived(Message m){
//do stuff
}
}
我试图让这段代码尽可能简单。想法是Listener正在等待从串行端口接收一些数据,并且当收到消息时,线程将对其进行一些处理。我更喜欢使用一些同步变量,如Message的BlockingQueue,但我无法修改Listener代码。当然,问题是运行循环会占用处理器周期。我的问题:
如果我在运行循环中等待或睡眠,函数调用是否仍然按预期工作? (我不确定如何测试它在100%的时间都有效。)
是否有更好的方法可以完全避免这种循环?
答案 0 :(得分:2)
做这样的事情
class MyThread implements Runnable, MessageListener{
private Listen Listener;
private Object lock = new Object();
public MyThread(){
Listener = new Listener(this);
}
public void run(){
while(true){
synchronized (lock) {
try{
lock.wait();
// use the updated status
}catch (Exception e) {
e.printStackTrace()
}
}
}
}
public void messageReceived(Message m){
synchronized (lock) {
try{
// Do something with the message here like update some status
lock.notify();
}catch (Exception e) {
e.printStackTrace()
}
}
}
获得活动后,您将更新某些状态/存储消息并释放通知线程。然后从你的线程处理事件
答案 1 :(得分:1)
仅仅根据您发布的内容,看起来有人误解了线程是什么以及它是如何工作的。如果while(true){}内部确实没有任何内容,并且不是因为简洁而将其剪切掉,那么在此线程上实际上不会处理该消息。
代码不在线程上运行“只是因为该方法是在runnable的实现上定义的。
调用messageReceived(Message m)
方法时,该方法的主体在调用线程中执行。它只是通过在那里被定义而不会被“传递”到这个线程。
答案 2 :(得分:0)
如果无事可做,则您的线程不需要存在。
class AsyncMessageListener implements MessageListener{
private final Listener listener;
private final ExecutorService services = Executors.newSingleThreadExecutor();
public MyThread(){
listener = new Listener(this);
}
public void messageReceived(final Message m){
services.submit(new Runnable() {
@Override
public void run() {
// process message m
}
});
}
}