有阵列链接端口[4],它被定义为静态和主线程的一部分。在我的项目中,有各种生产者和消费者线程通过使用静态引用来使用该数组,即使用类的名称来访问数组。在项目的某些部分,他的数组正在更新,正在读取此数组的项目的其他部分。我应该如何使用synchronized,wait,notify或join,以便保持代码的一致性?
R"(a\b\c\d)"
答案 0 :(得分:0)
服务器线程很可能是写入端口的线程,而工作线程服务于各个端口。在这种情况下,您可以使用读写锁。
ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
服务器线程:
class ServerThread extends Thread
{
readWriteLock.readLock().lock();
// read ports here
readWriteLock.readLock().unlock();
// if these ports need to be updated, acquire the write lock
readWriteLock.writeLock().lock();
// only one writer can enter this section,
// and only if no threads are currently reading.
readWriteLock.writeLock().unlock();
}
工作线程:
class WorkerThread extends Thread
{
readWriteLock.readLock().lock();
// read ports here, and service them
readWriteLock.readLock().unlock();
}
答案 1 :(得分:0)
即使ReentrantReadWriteLock
是一个不错的选择,您也可以考虑通过Optimistic Read
实施StampedLock
。当读者的数量远远大于作者的数量时,Optimistic Read
优于其他人。而且,在实际情况中,读取和写入操作很少同时发生。因此,乐观阅读在大多数时间都有效。
private final StampedLock stLock = new StampedLock();
<强>阅读器强>
long stamp = stLock.tryOptimisticRead();
// read ports here!
if (stLock.validate(stamp) == false) {
// optimistic reading fails (write occurred) - read again through read-lock.
stamp = stLock.readLock();
try {
// read ports here!
} finally {
stLock.unlockRead(stamp);
}
}
<强>作家强>
long stamp = stLock.writeLock();
try {
// write ports here!
} finally {
stLock.unlockWrite(stamp);
}
我应该如何使用synchronized,wait,notify或join,以便保持代码的一致性?
synchronized
- 您可以通过synchronized
保持一致性,但这不是一个好的选择。如果代码段或方法是synchronized
,则一次只能有一个线程执行该块或方法。在典型的读/写方案中,它不是有效的,因为多个读操作不是互斥的。
wait()/notify()
- 如果您的关注点只是获取最新值,则与wait()/notify()
无关。它们被设计为阻塞(释放)线程,直到(当)满足特定条件时。
join()
- 允许一个线程等到另一个线程完成执行。