我有一个要求,如下:
1)包含所有静态方法和静态列表的类。这个列表存储了一些对象,我对这些对象执行了一些操作。
2)现在这个操作被多个线程调用了。
3)此操作调用没有共享任何公共数据,因此此方法不同步。
4)现在,每当这个列表使用新对象更新时,我必须停止这个操作调用。
class StaticClass{
static List<SomeObjects>=new List<>();
static performOperation()
{
//call operation on all objects in the list
}
static updateList()
{
//update list, add, update or remove objects
}
}可能的解决方案:
1)同步performOperation()和updateList()。但是调用performOperation()的频率太高,更新列表的频率太低。
2)使用读写锁。在performOperation()中使用读锁,在updateList()中使用写锁。示例如下:
class StaticClass{
static List<SomeObjects>=new List<>();
static final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
static performOperation()
{
readWriteLock.readLock().lock();
//call operation on all objects in the list
readWriteLock.readLock().unlock();
}
static updateList()
{
readWriteLock.writeLock().lock();
//update list, add, update or remove objects
readWriteLock.writeLock().unlock();
}那么哪种解决方案更好呢?这是读写锁的正确用法吗?我之所以对方法2感到困惑,是因为performOperation()中没有需要读访问或写访问的数据。当list被更新时,我不能调用这个方法。所以我不确定这是否是读写锁的恰当使用。
发布于 2018-07-10 21:42:17
当发生大量读取时,ReadWriteLock会更有效,因为synchronized会阻塞所有内容。也就是说,ReadWriteLock更容易出错。例如,您的示例实际上将以死锁告终,因为每次您调用readWriteLock.writeLock()或readWriteLock.readLock()时,它都会创建一个新实例,并且永远不会解锁,从而导致它以死锁告终。所以你的例子应该看起来更像:
class StaticClass{
static List<SomeObjects>=new List<>();
static final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
static final Lock readLock = readWriteLock.readLock();
static final Lock writeLock = readWriteLock.writeLock();
static void performOperation()
{
readLock.lock();
try {
//call operation on all objects in the list
} finally {
// This ensures read lock is unlocked even when exception occurs
readLock.unlock();
}
}
static void updateList()
{
writeLock.lock();
try {
//update list, add, update or remove objects
} finally {
// This ensures read lock is unlocked even when exception occurs
writeLock.unlock();
}
}
}请注意,我还在这里添加了try/finally,以避免可能出现的异常问题。正如您所看到的,这比简单的synchronized部分要多得多。
此外,还有一种可能的替代CopyOnWriteArrayList。这是线程安全的,您不必使用锁或synchronized关键字。当有大量的写操作时,它会影响你的性能。
https://stackoverflow.com/questions/51266361
复制相似问题