2012-12-26 25 views
1

对标题的措辞感到抱歉,没有解释清楚。如果有人可以编辑它会很好:)如何允许多个方法同时运行,而某些其他方法未运行?

我有四种方法,访问共享状态。目前他们不是线程安全的。 共享状态是一个列表。其中两个方法修改列表,两个方法迭代它。可以简单地同步所有方法,但这会导致性能下降 - 只要没有修改方法在运行,迭代方法就可以在多个线程中同时运行,这是非常安全的。

一种允许多个阅读器运行的锁定方法,或者需要一个写入器。

private List<T> list; 
public void insert(T t) {// Write shared state 
    list.add(t); 
} 
public void remove(T t) {// Write shared state 
    list.remove(t); 
} 
public void doStuff(T t) {// Read shared state 
    // iterate list and do stuff 
} 
public void doOtherStuff() {// Read shared state 
    // iterate list and do stuff 
} 
+0

线程都在使用这里,我很想改变设计,使这种不必要的,但我不能,因为我修补别人的代码以使其并发并需要尽可能保持与原始设计类似。 –

+0

更多的细节可能会有所帮助。为什么某些方法可以同时运行,而某些方法不能?这是因为他们正在访问某个共享资源或共享状态吗? –

+0

共享状态 - 一个阵列列表,a和b修改而c和d只能迭代。 –

回答

2

很可能ReadWriteLock符合您的需求。线程ab应该获得write锁,而线cd应该获得阅读一个

+0

据我所见,正是我需要的!谢谢 –

+0

3年后更新:ReadWriteLock库不支持双向重入。我最终创建了[此实现](https://github.com/nallar/TickThreading/blob/master/src/main/java/nallar/tickthreading/util/concurrent/TwoWayReentrantReadWriteLock.java)。 –

2

您可以使用Java的​​关键字执行此操作。该关键字会在某个对象上创建一个锁,所以除非该锁被打开(并且在运行时它会调用锁),否则您将无法运行某个对象。在这种情况下,您需要两个锁,并且您必须锁定某个对象,因此您可以创建两个锁并锁定它们。你需要的是这样的:

A/B:

synchronized(lock1) 
{ 
    synchronized(lock2) 
    { 
     //do stuff 
    } 
} 

C:

synchronized(lock1) 
{ 
    //do stuff 
} 

d:分别锁1和锁2

synchronized(lock2) 
{ 
    //do stuff 
} 

c和d锁,不会相互冲突,所以可以同时运行。但是,a和b要求这两个锁都是空闲的以便运行,因此不能与任何其他方法并发。

+1

这可以防止d/c与自身同时运行。 –

+0

不一定。如果你创建一个新类,c和d将会与其他实例的c和d同时运行。 – Hoeloe

+0

我应该已经明确要求了。 c和d需要在类的一个实例中同时运行。 –