2016-03-29 9 views
-1

java内の別の関数から関数をロックする必要があります。上記の例では、スレーブ機能をprint counterに呼び出します。マスタ関数が呼び出された場合、スレーブ関数を呼び出すすべてのスレッドは、マスタ関数を終了する必要があります。java内の別の関数から関数をロックする

どうすればいいですか?

int counter = 0; 

private void slave() 
{ 
    System.out.println(counter); 
} 

private void master() 
{ 
    lockSlave(); 
    counter ++; 
    unlockSlave(); 
} 
+0

本当にこの特定のタスクにはロックは必要ありません。 [AtomicInteger'](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html)または['LongAdder'](https:// docs .oracle.com/javase/8/docs/api/java/util/concurrent/atomic/LongAdder.html) –

+0

これはあなたが知っている単なる例です。私のリポジトリの実際のスレーブ機能には、基本カウンタではなく、複雑なアルゴリズムがたくさん含まれています。 @SashaSalauyou – neverwinter

+0

はい私は理解しています。並行処理プログラミングに非常に役立つ別のJDKコンポーネントに注意を向けようとしました。 –

答えて

2

JDK ReentrantReadWriteLockをご覧ください。

private final ReadWriteLock lock = new ReentrantReadWriteLock(); 

private void slave() 
{ 
    lock.readLock().lock(); 
    try { 
     System.out.println(counter); 
     ... 
    } finally { 
     lock.readLock().unlock(); 
    } 
} 

private void master() 
{ 
    lock.writeLock().lock(); 
    try { 
     counter ++; 
     ... 
    } finally { 
     lock.writeLock().unlock(); 
    } 
} 
+2

カウンタがスレッドセーフである場合、ロックは必要ありません。 'counter ++ 'ごとにロックが取得された場合、スレッドセーブや揮発性の必要はありません –

+1

あなたは正しいです。更新しました。 –

2

ReentrantReadWriteLockを使用してください。また、変更をすべてのスレッドが見ることができるように変数を揮発性にします。

ReadWriteLock m_lock = new ReentrantReadWriteLock(); 
Lock m_readLock = m_lock.readLock(); 
Lock m_writeLock = m_lock.writeLock(); 

volatile int counter = 0; 

private void slave() { 
    m_readLock.lock(); 
    try { 
    System.out.println(counter); 
    } finally { 
    m_readLock.unlock(); 
    } 
} 

private void master(){ 
    m_writeLock.lock(); 
    try { 
    counter ++; 
    } finally { 
    m_writeLock.unlock(); 
    } 
} 
+2

一般的なイディオムは、その内部ではなく、「試行」の前にロックを取得することです。https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Lock.html As '.lock()'自体がスローされる可能性があります。その後、 'finally'に例外が発生します。 –

+1

あなたは正しいです。私は自分の答えを更新しました。 – f1sh

-1

同期ワードを使用すると、完全な方法を同期させることができるため、一度に1つのスレッドしか実行できません。

+1

それは本当です。しかし、 "ロックする"方法は1つしかありませんが、問題は2つの異なる方法についてです。 – f1sh

関連する問題