2015-07-06 2 views
1

У меня есть следующий класс:Разрешить только один поток в то время, чтобы использовать объект

public class MyClass{ 

    private List<Integer> ints = new LinkedList<Integer>(); 

    public List<Integer> getInts(){ 
     return ints; 
    } 

    public synchronized void doAction(){ 
     //Do some with the list 
    } 
} 

мне нужно, чтобы только один поток в то время в виде доступа к List. Я хотел бы сделать это следующим:

public class MyClass{ 

    private List<Integer> ints = new LinkedList<Integer>(); 
    private static final Semaphore s = new Semaphore(1); 

    public List<Integer> getInts(){ 
     s.acquire(); 
     return ints; 
    } 

    public void release(){ 
     s.release(); 
    } 

    public synchronized void doAction(){ 
     s.acquire(); 
     //Do some with the list 
     s.release(); 
    } 
} 

Но implementaion, очевидно, не является надежным, потому что, если запрос клиента по List через геттер для добавления некоторых элементов в ней и забыть вызвать release() мы получим в неприятности, если это попробуйте вызвать метод doAction.

Какое решение проблемы?

+0

Kayaman имеет правильный ответ здесь, но и в будущем, если вы думаете, что вы хотите использовать 'Semaphore' таким образом, рассмотреть возможность использования' java.util.concurrent.Lock' вместо этого. –

ответ

4

Не разрешайте клиенту получать ссылку. Поместите все методы, которые работают в списке, на MyClass и синхронизируйте их.

Однако вы можете разрешить пользователям получать копию моментального снимка списка.

+0

Хороший совет, действительно. – user3663882

2

Вы можете использовать синхронизированный список:

private List<Integer> ints = Collections.synchronizedList(new LinkedList<Integer>()); 
+2

Но это не обеспечит синхронизацию по итерации, например. – Kayaman

+0

@ Kayaman Вы имеете в виду, если мы какой-то поток меняем список, а другой печатает его содержимое через итерацию, мы получим не совсем то, что хотели ... – user3663882

+0

Точно. Тогда вам нужно было бы верить, что любой итерирующий поток будет синхронизироваться в списке. – Kayaman

Смежные вопросы