2015-03-19 2 views
-1

У меня есть некоторые проблемы с использованием синхронизированного ключевого слова в java. Я понимаю часть, где потоки получают блокировки на методах или блоках кода, но я не знаю, как использовать ее в следующем примере.Могу ли я синхронизировать 2 разных метода? java

У меня есть 2 разных потока (Thread A и Thead B), а Class1, содержащий список, содержит экземпляры Class2. Класс1.methodA(), вызываемый threadA, изменяет информацию в списке. Класс1.methodB(), вызываемый threadB, использует только информацию в списке.

Я пришел к выводу, что проблемы, которые возникают у меня в программе, происходят, когда Thread A изменяет данные в списке, пока Thread B его использует.

Должен ли я создать синхронизированный метод внутри Class1, который вызывает вызовы MethodA или MethodB (кажется мне лишним). Или может ли поток получить блокировку только на конкретном экземпляре класса 2, который изменяется?

Прошу прощения за любой плохой английский.

ответ

0

Есть оба метода syncrhonize в списке:

methodA() 
{ 
    synchronized(list) 
    { 
     ... use the list, no one else can touch it 
    } 
    ... do other stuff. 
} 

же для methodB()

More info here.

+0

спасибо. Таким образом, поток получает блокировку в списке вместо блокировки блока кода? –

+0

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

0

Существует свое объяснение о многопотоковости here

Ну, вернемся к вашему вопросу. Фактически вы можете просто использовать синхронизацию в своем списке и выполнять чтение или добавление в этот блок синхронизации.

synchronized(yourList) 
{ 
    // do something 
} 

В противном случае я думаю, вы можете использовать CopyOnWriteArrayList (API) из java.util.concurrent пакета. Но это действительно дорого, потому что он всегда создает новую копию базового массива.

CopyOnWriteArrayList<String> myArrayList = new CopyOnWriteArrayList<String>(); 

myArrayList .add("Stackoverflow"); 

Iterator<String> iterator = myArrayList .iterator(); 

while (iterator.hasNext()) 
    System.out.println(iterator.next()); 
} 

Другой метод должен был бы использовать synchronizedList

List list = Collections.synchronizedList(new ArrayList()); 

synchronized(list) { 
    Iterator i = list.iterator(); 
    while (i.hasNext()) 
     foo(i.next()); 
} 

Но вы по-прежнему нужен синхронизированный блок в конце. Методы добавления и удаления сами по себе являются атомарными и потокобезопасными, но итерации по списку нет.

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