2009-12-05 3 views
8

두 개의 배열이 있고 스레드 간 액세스를 동기화해야합니다. 나는 그것들을 동기화 된 블록에 넣을 것이다. 문제는, 나는 그들 중 단 하나만 통과 시켜서 '동기화 된'상태로 만들 수 있다는 것이다.두 개 이상의 객체에 대해 자바 동기화 된 블록이 있습니까?

두 배열에 대한 액세스가 동기화되었는지 어떻게 확인합니까? 클래스에 넣고 객체를 만드나요? 또는 동기화 된 블록에서만 다른 배열에 액세스합니다. 그러면 동기화 된 액세스가 처리됩니다.

감사합니다, 당신은 이렇게하지 을 무엇 이건

+0

새로운 수업에 추가하면 도움이 될 수 있으므로 원하는 것을 명확히하는 데 도움이 될 수 있습니다. 그러나 스레드 안전성에 전혀 영향을 미치지 않습니다. 나는 명시 적 잠금 (아래)을 사용하는 대답을 좋아한다. –

답변

20

:

synchronized (array1) { 
    synchronized (array2) { 
    // do stuff 
    } 
} 

당신은 매우 조심하지 않으면이 deadlock으로 이어질 가능성이 높습니다. 이 방법을 사용하는 경우 함정에 대한 토론을 위해 Google의 "식사 철학자"와 같은 부분 순서가 변경되지 않도록해야합니다.

은 기본적으로 당신이해야 할 일은 당신이 배열 중 하나에 액세스하려면 사용 후 모든 배열 액세스를 이용합니다 하나의 잠금 개체를 만드는 것입니다. 거칠지 만 안전합니다. 당신은 당신이 ReadWriteLock 같은 자바 5+ 동시 유틸리티를 사용하려는 세분화 된 방법을 필요로하지만,이 더 구현하기가 복잡하고 오류가 발생하기 쉬운 될 경우

public static class TwoArrays { 
    private int[] array1 = ... 
    private int[] array2 = ... 
    private final Object LOCK = new Object(); 

    public void doUpdate() { 
    synchronized (LOCK) { 
     ... 
    } 
    } 
} 

: 당신은 이런 식으로 할 수 있습니다. 이 같은

+1

당신은'doUpdate'를'LOCK' 객체의 복잡성을 추가하기보다는 동기화시킬 수 있습니다. – skaffman

+3

사실, 자물쇠로 사용하지 않을 때 자물쇠를 드러내지 않는 것이 가장 좋습니다. – cletus

+0

이것은 질문을 발생시킵니다. 동일한 객체에 다른 동기화가있을 경우 중첩 된 동기화 된 블록을 사용하면 교착 상태가 발생할 수 있습니다. 그러나 위의 코드 만 존재할 때 발생합니까? 아직 array1의 모니터가없는 경우 스레드는 array2의 모니터를 확보 할 수 없습니다. 그리고 그것이 array1의 모니터를 가지고 있다면, 다른 스레드는 array2의 모니터를 가질 수 없습니다. 나는 이성에 구멍이 있습니까? – Bozho

11

자바 5 이전에, 내가 쓴 것 일 :

// pre Java 5 code: 
Object lock = new Object(); 
// ... 
synchronized(lock) { 
    // do something that requires synchronized access 
} 

그러나 자바 5, 나는 java.util.concurrent.locks (에서 클래스를 사용하는 것 때문에 개인적으로, 나는 이것이 더 복잡하거나 오류가 발견하지 않습니다 -prone) :

private ReadWriteLock rwl = new ReentrantReadWriteLock(); 
private Lock rLock = rwl.readLock(); 
private Lock wLock = rwl.writeLock(); 

private List<String> data = new ArrayList<String>(); 

public String getData(int index) { 
    rLock.lock(); 
    try { 
     return data.get(index); 
    } finally { 
     rLock.unlock(); 
    } 
} 

public void addData(int index, String element) { 
    wLock.lock(); 
    try { 
     data.add(index, element); 
    } finally { 
     wLock.unlock(); 
    } 
} 
: 당신이 잠금 읽기 - 쓰기가 필요한 경우

// Java 5 Code Using Locks 
Lock lock = // ... 
lock.lock(); 
try { 
    // do something that requires synchronized access 
} 
finally { 
    lock.unlock(); 
} 

, 여기에 자바 5에서 읽기 - 쓰기 잠금을 사용하여 구현 예이다

물론 필요에 맞게 수정하십시오.

관련 문제