如何同步2个线程来处理列表中的数据?
我想在显示列表时“通知”主题B 。在阅读列表时,不能通过主题A 更改它。当主题B 完成阅读时,主题A 可以再次开始更改列表。
我的猜测是
synchronized(obj)
list.wait()
+ list.notify()
线程没有互相调用。它们一直在并发运行。
答案 0 :(得分:0)
您可以将所有更改放在Runnables中,并将它们放入线程A按顺序执行的队列中。在每个作业之后,A必须生成修改后的列表的快照并将其提交给线程B.您可以使用执行程序。
答案 1 :(得分:0)
一般概念(我在你的案例中看到的)如下:
1)创建您计划使用的List
实例。
2)编写与thread A
和thread B
相对应的2个类,这两个类都实现Runnable
并将List
作为构造函数参数。
3)在列表实例上同步这两个类:
// method in class that adds
public void add() {
synchronized(list) {
// perform addition ...
list.notify();
}
}
// method in class that reads
public void read() throws InterruptedException {
synchronized(list) {
while (list.isEmpty())
list.wait();
// process data ...
}
}
4)使用与这两个类的实例对应的argumens创建2个线程并启动它们。
答案 2 :(得分:0)
我尝试了建议here或here的并发包,但效果很好。线程相互锁定:
final Lock lock = new ReentrantLock(true);
// thread A
lock.lock();
// write to list
lock.unlock();
// thread B
lock.lock();
// read from list
lock.unlock();
不确定他们是否可以一个接一个地执行,我没有得到通知功能。但这并没有损害我的申请。
答案 3 :(得分:0)
Reader and writer locks是你的朋友。
•线程A正在添加/更改列表中的项目(写入列表)
...所以它可以使用写锁...
•线程B显示项目(仅读取列表)
...所以它可以使用读锁定。
让我们假设你正在使用一些直接用于等待/通知的东西(例如,内置的Object方法)来阻止读取和显示线程。那时,您的代码看起来像这样:
/** This is the read/write lock that both threads can see */
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
/** This method is called by thread A (the writer / modifier) */
public void add() {
try {
// Only one writer at a time allowed
lock.writeLock().lock();
// Insert code here: Add to the list
} finally {
// Unlock in the finally block to ensure that lock is released
lock.writeLock().unlock();
}
// Notify anyone who's waiting for data
list.notify();
}
/** This method is called by thread B (the reader / displayer) */
public void read() throws InterruptedException {
try {
// As many readers as you like at a time
lock.readLock().lock();
// Insert code here: read from the list
} finally {
// Unlock in the finally block to ensure that lock is released
lock.readLock().unlock();
}
// Wait for new data
list.wait();
}
为了使事情更方便,您可以使用阻塞数据结构来消除通知/等待消息:例如,BlockingQueues之一。在这种情况下,您根本不会写任何通知。阅读器阻止等待新数据。当编写器将数据添加到队列时,读取器将解除阻塞,排出新数据以进行处理,执行其操作然后再次阻塞。