4

入力に基づいて関数を同期する必要がある状況になりました。例えば。機能があります。func(int a) --- この関数は、同じ入力整数でこの関数を呼び出そうとするスレッドをブロックしたい多くのスレッドから呼び出すことができます。それ以外の場合は、続行せずに続行させます。関数を書きました

HashTable<Integer> check=new Hashtable<Integer>();

func(int a){

Integer lock=check.get(a);
if(lock==null){
check.put(a);
}else{
check.put(a);
}
synchronized(lock){
//do something....

} }

これが正しいかどうか教えてください。また、これ以外の解決策があれば。私は理解しようとしています。答えが見つかったら投稿します。

4

1 に答える 1

1

1)ロックの取得も同期ブロックにある必要があります

2) メモリ リークがある - 未使用のロックを削除しない

私はこのようにします

Map<Integer, Lock> map = new HashMap<>();

static class Lock {
    int count = 1;
}

void func(int i) {
    Object lock = getLock(i);
    try {
        synchronized (lock) {
            //
        }
    } finally {
        releaseLock(i);
    }
}

private synchronized Object getLock(int i) {
    Lock lock = map.get(i);
    if (lock != null) {
        lock.count++;
    } else {
        lock = new Lock();
        map.put(i, lock);
    }
    return lock;
}

private synchronized void releaseLock(int i) {
    Lock lock = map.get(i);
    if (--lock.count == 0) {
        map.remove(i);   
    }
}
于 2013-05-13T02:18:50.210 に答える