如何同步2个线程来处理列表中的数据?Java - 如何同步2列表上的2个线程?
- 线程A被追加/变更列表中的项目(写入到列表)
- 线程B正在显示的项目(仅读出该列表)
我想以“通知”线程B何时可以显示该列表。在阅读清单时,不得更改线程A。当线程B完成读取,线程A可以开始再次更改列表。
我的猜测去
synchronized(obj)
list.wait()
+list.notify()
线程不调用对方。他们一直在同时运行。
如何同步2个线程来处理列表中的数据?Java - 如何同步2列表上的2个线程?
我想以“通知”线程B何时可以显示该列表。在阅读清单时,不得更改线程A。当线程B完成读取,线程A可以开始再次更改列表。
我的猜测去
synchronized(obj)
list.wait()
+ list.notify()
线程不调用对方。他们一直在同时运行。
您可以将所有更改放入Runnable中,并将它们放入Thread A按顺序执行的队列中。每个作业完成后,A必须生成修改后的列表的快照并将其提交给线程B.您可以使用Executors。
一般概念(正如我在你的案例中看到的)将如下。
1)创建一个您计划使用的List
实例。
2)写入对应于您的thread A
和thread B
2类,都实现Runnable
,并采取List
作为其构造函数的参数。
3)上列表实例同步这些2类:
// 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)与对应于这2个类的实例argumens和启动它们创建2个线程。
这就是我想要做的,但总是以死锁,IllegalMonitoExceptions或非同步执行结束。因为它运作良好,我会与ReentrantLock一起去。 – Bitterblue 2013-04-30 10:11:17
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之一。在这种情况下,你根本不写任何通知。读者阻止等待新数据。当写入者将数据添加到队列中时,读者将取消阻止,排除新数据以处理,执行其操作,然后再次阻止。
有趣。但Q更简单(只是同步读写器)。或者这是否比简单的ReentrantLock有一些好处? – Bitterblue 2014-04-07 07:47:35
@ mini-me,是的,如果你有一个读者和作者不平衡的情况:例如,读者多于作者,写作所花费的时间比阅读或其他例子少。读/写锁中还有额外的逻辑:任意数量的读者对比只有一个作者,如果一个作者请求锁,没有更多的读者等等。 – 2014-04-07 11:46:17
你可以显示一点你打算使用的代码吗? – 2013-04-30 08:52:08
为什么不只是同步使用该列表中的数据的方法? – gurvinder372 2013-04-30 08:52:45
重复线程。 请参阅 –
Qylin
2013-04-30 08:54:49