Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > И опять синхронизация


Автор: nucer 24.5.2009, 17:56
В общем к примеру есть такая штука
Код

class Some
{
  private ArrayList list;
  public void read()
  {
     //чтение некоторых данных из list
  }
  
  public void write()
  {
    //запись некоторых данных в list
  }
}


собственно вопрос: как обеспечить синхронизацию методов read и write таким образом, чтобы read и write "блочили" друг друга, а также write и write блочили, а read и read не блочили??
Т.е. если сейчас пишется что то туда, то чтение или запись должны подождать, но чтобы несколько операций чтения (без записи) могли выполнялняться асинхронно...

Автор: susanin 24.5.2009, 18:50
есть класс ReentrantReadWriteLock....как раз отвечает за это....полагаю надо смотреть в его сторону..

Автор: jManiak 24.5.2009, 23:51
А почему не воспользоваться сигнальной переменной? 
Например:
Код

class Some
{
  private ArrayList list;
  private boolean isLocked = false;

  public void read()
  {
      while (isLocked) {
          wait(500);
      }
      isLocked = true;
      //чтение некоторых данных из list
      isLocked = false;
  }
  
  public void write()
  {
      while (isLocked) {
          wait(500);
      }
      isLocked = true;
      //запись некоторых данных в list
      isLocked = false;
  }
}

Автор: tux 25.5.2009, 05:33
Цитата(jManiak @  24.5.2009,  23:51 Найти цитируемый пост)
А почему не воспользоваться сигнальной переменной? 

Потому что в многопоточной среде такой способ не работает - http://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B5_%D0%B3%D0%BE%D0%BD%D0%BA%D0%B8.

Автор: Fieral 25.5.2009, 13:01
Код

class Some {
        private ArrayList list;

        private ReentrantLock L = new ReentrantLock(true);

        public void read()
      {
    L.lock
    try{

         //чтение некоторых данных из list
    }finally{
    L.unlock();}
      }

        public void write()
      {

    L.lock
    try{

        //запись некоторых данных в list
    }finally{
    L.unlock();}


      }
    }



?

Добавлено через 11 минут и 58 секунд
jManiak, особенно внимательно прочитайте "Случай с Therac-25" по ссылке данной tux.

Автор: SoulKeeper 25.5.2009, 13:19
Надо использовать не ReentrantLock, а ReentrantReadWriteLock

Автор: jManiak 25.5.2009, 14:33
Ну да, может быть большой ОЙ...
Пойду переделывать в одном месте.

Автор: nucer 25.5.2009, 20:18
2susanin за ReentrantReadWriteLock спасибо, вроде то что надо! )
Правда код из примера немного смущает....
Код
class RWDictionary {
    private final Map<String, Data>  m = new TreeMap<String, Data>();
    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    private final Lock r = rwl.readLock();
    private final Lock w = rwl.writeLock();

    public Data get(String key) {
        r.lock(); try { return m.get(key); } finally { r.unlock(); }
    }
    public String[] allKeys() {
        r.lock(); try { return m.keySet().toArray(); } finally { r.unlock(); }
    }
    public Data put(String key, Data value) {
        w.lock(); try { return m.put(key, value); } finally { w.unlock(); }
    }
    public void clear() {
        w.lock(); try { m.clear(); } finally { w.unlock(); }
    }
 }

Везде try и catch, разве это не херит производительность на корню? Вроде я даже читал где то, что try и catch следует стараться избегать и юзать предварительные проверки везде где возможно...

2Maniak 
Цитата
while (isLocked) {
          wait(500);
      }
 такой способ подходит разве что для проектирования п/о к дверце http://filesupload.narod.ru/dachia/PICT0172.JPG  smile  smile 

Автор: susanin 25.5.2009, 20:36
Цитата(nucer @  25.5.2009,  20:18 Найти цитируемый пост)
Везде try и catch, разве это не херит производительность на корню? Вроде я даже читал где то, что try и catch следует стараться избегать и юзать предварительные проверки везде где возможно...

ну так а без них никуда....исключения приходится ловить...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)