2012-09-21 61 views
1

我一直在使用Java的​​塊來使我的代碼線程安全。我將數據結構移植到java,通常可以使用​​塊,但我並不總是知道如何以典型的Java方式使用它們。如何有條件地鎖定Java?

這裏是一個場景的例子:

myMethod (Bool useLock) 
    { 
    if (useLock) 
     { 
     //locks the following section of code until unlocked. 
     lockObject.lock(); 
     } 

    //do more stuff.... 

    if (useLock) 
     { 
     //unlocks exclusive control of code. 
     lockObject.unlock(); 
     } 
    } 

我怎麼做的這個Java中的等價物?在這段代碼中,有時候我想鎖定,有時候我不想,但是我想對它做出明智的決定,而不必編寫相同代碼的兩個版本。除了使用​​塊之外,還有其他的Java鎖定方法嗎?

回答

4

您可以使用Lock對象,特別是ReentrantLock應該做的工作。 http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html

或者您仍然可以使用​​塊來解決問題。從你的問題的代碼如下:

myMethod (Bool useLock) { 
    if (useLock) { 
     synchronized (this) { 
      criticalSection(); 
     } 
    } else { 
     criticalSection(); 
    } 
} 

criticalSection() { 
    //do more stuff.... 
} 

或者,如果你想保證類的不同實例之間的相互排斥,你應該使用其他監視器對象比this。例如TheClassName.class或該類的其他顯式定義的靜態變量。

+0

他已經指定了一個鎖定對象:'lockObject'。而'Bool'不是標準的Java類。 – m0skit0

+0

我最終使用了你的同步解決方案。我看着ReentrantLock的,非常感謝!但是它們似乎不是同步塊的互斥。 – Jon

1

你可以使用不安全的monitorEnter和monitorExit,但這是一個壞主意恕我直言。

如果不需要鎖定,JVM幾乎可以在任何情況下優化它們。如果只有一個線程獲得它,​​是非常有效的。 (不像鎖例如)

1

除了使用同步塊以外,還有其他的Java鎖定方式嗎?

是 - java.util.concurrent.locks,尤其是ReentrantLock類,但彼得說,如果你可以只使用​​擺脫它很可能會更有效的整體(以及更易於維護,特別是如果你的工作作爲一個團隊的一部分)。

2

我想ReentrantLock可以在場景中使用

final Lock lock = new ReentrantLock(); 

示例代碼段

class X { 
private final ReentrantLock lock = new ReentrantLock(); 
// ... 

public void m() { 
    lock.lock(); // block until condition holds 
    try { 
    // ... method body 
    } finally { 
    lock.unlock() 
    } 
    } 
} 
1

您可以使用Java lock對象和Condition對象。 Condition class'java docs也給出了很好的例子isFullisEmpty

就你而言,我猜你可以利用條件對象使代碼更易讀懂。像這樣:

final Lock lock = new ReentrantLock(); 
final Condition useLock = lock.newCondition(); 

並使用適當的條件。

1

一些很好的答案已經發布,但我想添加其他的解決方案,爲我工作:

我開始:

... 
synchronized(<lockobject>) { 
<huge section of code with lots of variables> 
} 
... 

將其改爲:

... 
synchronized(<condition> ? <lockobject> : new Object()) { 
<huge section of code with lots of variables> 
} 
... 

基本上,如果條件是真的,它使用lockobject同步來執行代碼,但是如果條件爲false,它會使用「new Object()」,它基本上可以讓它在沒有任何同步的情況下運行。