在线程间通信时遇到问题,并通过在整个地方使用“虚拟消息”来“解决”它。这是一个坏主意吗?有什么解决方法?生产者 - 消费者线程间通信
示例我有问题。
主线程启动一个处理线程并将记录插入到数据库中。 主线程读取一个可能很大的文件,并将一个记录(对象)放入另一个记录(对象)中。处理线程从队列中读取并确实工作。
如何告诉“处理线程”停止? 队列可以是空的,但工作没有完成,并且主线程现在不会在处理线程完成工作并且不能中断它时。
所以处理线程做
while (queue.size() > 0 || !Thread.currentThread().isInterrupted()) {
MyObject object= queue.poll(100, TimeUnit.MILLISECONDS);
if (object != null) {
String data = object.getData();
if (data.equals("END")) {
break;
}
// do work
}
}
// clean-up
synchronized queue) {
queue.notifyAll();
}
return;
和主线程
// ...start processing thread...
while(reader.hasNext(){
// ...read whole file and put data in queue...
}
MyObject dummy = new MyObject();
dummy.setData("END");
queue.put(dummy);
//Note: empty queue here means work is done
while (queue.size() > 0) {
synchronized (queue) {
queue.wait(500); // over-cautios locking prevention i guess
}
}
注意,插入必须在同一个事务和事务不能由主线程来处理 。
这样做会更好吗? (我正在学习,不想以“错误的方式开始”)
好的。如果传递的对象的类型没有可以轻易用于此的String字段,我将如何使用它?如果任何文本可能是有效的数据,因此可能等于毒药?使用GUID? – 2011-12-22 14:01:28
理想情况下,您可以更改MyObject类并在其中添加isPoison()方法。这种方法如何确定对象是否是毒药取决于你,可能是一个简单的事情,比如比较消息是否为空,或者消息是否明确创建为毒药。一个想法是将MyObject重构为两个实现的接口,一个始终在isPoison()方法中返回false的MessageObject和一个始终返回true的PoisonMessage。但是,这很大程度上取决于你在做什么,根据你的真实情况可能会有更好的解决方案。 – 2011-12-22 14:08:54