2015-01-19 4 views
0

Может кто-нибудь скажет мне, если поток Java, выполняющий команду запуска в «myClass» (в следующем коде), теряет синхронизацию объекта между тем временем, когда команда getL() CustomList получает его и время когда запуск myClass запрашивает синхронизацию одного и того же объекта?Синхронизация по кодовой цепочке

Если начальный поток поддерживает синхронизацию, тогда центральный код «myThread», созданный командой get CustomList, никогда не сможет запускаться до тех пор, пока исходный поток не будет завершен запрошенным объектом.

public class myClass implements Runnable { 

    private CustomList list; 

    public myClass(){ 
     list = new CustomList(); 
     //Code to pack "list" goes here. 
    } 

    public void run(){ 
     int position = 0; 
     while(position<list.size()){ 
      synchronized(list.get(position)){ 
       //Opperation's central code. 
      } 
      position++; 
     } 
    } 

    public class CustomList extends ArrayList<Object> { 

     public CustomList(){ 
      super(); 
     } 

     public Object get(int i){ 
      Object o = super.get(i); 
      synchronized(o){ 
       myThread thread = new myThread(o); 
       thread.start(); 
       return o; 
      } 
     } 

    } 

    public class myThread extends Thread { 

     private Object subject; 

     public myThread(Object o){ 
      subject = o; 
     } 

     public void run(){ 
      synchronized(subject){ 
       //Do something to "subject" 
       //BUT only AFTER the original Thread is finished with it. 
      } 
     } 

    } 

} 
+0

Какую цель ставите перед собой? Кроме того, насколько вы сейчас понимаете «синхронизированный»? – immibis

+0

По сути, моя конечная цель - иметь объект, который распределяет объекты (как и List или Map), специально предназначенные для использования в синхронной (Object) команде. Я хочу, чтобы устройство раздатчика регистрировало каждый такой запрос для объекта со вторым потоком, так что второй поток попытается синхронизироваться с этим же объектом, а затем выполнить операцию над ним, но * ТОЛЬКО *, когда начальный поток, который запросил объект завершен с ним. (т. е. отменил синхронизацию с объектом). – Cambot

+0

Мое намерение состояло в том, чтобы передать объект второму потоку в синхронизированной скобке функции getList CustomList перед линией возврата. Или, по крайней мере, в сопоставимом месте в моем собственном коде. Но если синхронизация не выполняется в моем примере выше, как указывает gkincker, то, похоже, мне придется найти другой способ выполнить это. – Cambot

ответ

3

Ответ на этот вопрос да. Ваш CustomList не является потокобезопасным с учетом кода, который вы представили.

Чтобы устранить проблему, прекратите попытки пользовательской синхронизации. Вы еще недостаточно хорошо это понимаете. Вместо этого используйте java.util.Collections.synchronizedList(), чтобы обернуть экземпляр java.util.ArrayList.

private List<Object> list = Collections.synchronizedList(new ArrayList<Object>()); 
+0

Downvoted, потому что даже с synchronizedList здесь может быть состояние гонки, потому что мы не знаем, что пытается сделать ассер. – immibis

+0

Aaand теперь я не могу отказаться от ниспроверки, так как искатель уточнил, что они только спрашивают об этом конкретном вопросе, а не об исправлении их кода. Хорошая работа StackOverflow. Извини за это. – immibis

+0

@immibis Я сделал тривиальное изменение в своем ответе, чтобы вы могли удалить ваш downvote :) – gknicker

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