我在这里有这个计时器:
timer = new Timer(delay, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
doWork();
} catch (JMSException e1) {
e1.printStackTrace();
}
}
});
timer.start();
调用此代码:
public void doWork() throws JMSException {
String fileContent = getFileContent();
Session session = queue.getConnection().createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination dest = session.createQueue(queue.getName());
MessageProducer producer = session.createProducer(dest);
TextMessage message = session.createTextMessage();
//Different and not less than to be able to create permanent producers
for (int i = 0; i != numberOfMsgsInBurst; i++) {
message.setText(fileContent);
producer.send(message);
}
/*
* Send a non-text control message indicating end of messages.
*/
producer.send(session.createMessage());
}
据我所知,当计时器调用doWork时,它会阻塞系统(例如GUI)。我希望能够永久运行此doWork方法(将numberOfMsgsInBurst设置为-1),因此生产者将永久生成消息。 我遇到的问题是它阻塞了系统,因此系统停止响应。
有什么方法可以在后台线程中触发此事件吗?
谢谢, 奥斯卡
答案 0 :(得分:3)
您可以在线程中启动doWork():
public void actionPerformed(ActionEvent e) {
Thread t = new Thread() {
@Override
public void run() {
try {
doWork();
} catch (JMSException e1) {
e1.printStackTrace();
}
}
};
t.start();
}
答案 1 :(得分:2)
javax.swing.Timer
在事件派发线程上执行ActionListener
回调。这意味着您的代码必须快速返回,否则GUI将冻结。
如果要在其他线程上运行此任务,可以考虑使用java.util.Timer
类。与每次调用Thread
doWork
时产生新Thread
相比,这将更加清晰,资源消耗更少(创建新的{{1}}是昂贵的。)
答案 2 :(得分:0)
我会创建一些事件对象的同步队列(LinkedBlockingQueue是一个很好的例子)。然后timer事件只是将一个对象放入队列,处理线程将从队列中取出()对象,并在下一个对象可用时进行处理(take()自动等待它。)