2012-02-03 3 views
4

У меня есть класс с именем «Канал» с двумя методами определены:Синхронизация картины

class Channel { 

    void read(){...} 
    void write(){...} 
} 

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

Каким будет наиболее подходящий шаблон для реализации такого поведения? Может быть, классы java или библиотеки помогут?

ответ

7

Использовать ReadWriteLock. Это позволит выполнять параллельные чтения с последовательной записью. Чтобы дополнительно удовлетворить ваши требования, приобретение writeLock будет препятствовать достижению прогресса readLock до следующего выпуска.

class Channel { 
    final ReadWriteLock lock = new ReentrantReadWriteLock(); 

    void read(){ 
     lock.readLock().lock(); 
     try{ 

     }finally{ 
     lock.readLock().unlock(); 
     } 
    } 
    void write(){ 
     lock.writeLock().lock(); 
     try{ 

     }finally{ 
     lock.writeLock().unlock(); 
     } 
    } 
} 
+1

Может быть в Java 8 мы будем, наконец, попробовать-с-ресурса :( – stefan

+0

@stefan Java 7 «означает» есть, что, хотя она работает только с классом, который реализует AutoCloseable. Если Java 8 приходит с закрытие этого кода может выглядеть намного приятнее –

+0

О, сладкий, я подумал, что его достали. Время играть: D – stefan

1

Для удовольствия, вот реализация с использованием новой функции Java 7 try-with-resources.

class RWLock { 
    class ACLock extends ReentrantLock implements AutoCloseable { 
     public void close() { 
      this.unlock(); 
     } 
    } 

    private ACLock readLock = ACLock(); 
    private ACLock writeLock = ACLock(); 
    private int numReaders = 0 

    public AutoCloseable write() { 
     readLock.lock(); 
     writeLock.lock(); 
     return new AutoCloseable() { 
      public void close() { 
       writeLock.close(); 
       readLock.close(); 
      } 
     } 
    } 

    public AutoCloseable read() { 
     try (ACLock read = readLock.acquire()) { 
      if (numReaders == 0) { 
       writeLock.lock(); 
      } 
      numReaders++; 
     } 
     return new AutoCloseable() { 
      public void close() { 
       numReaders--; 
       if (numReaders == 0) { 
        writeLock.unlock(); 
       } 
      } 
     } 
    } 

    // Here's how you use them 
    public static void main(String[] args) { 
     RWLock lock = RWLock(); 
     try (AutoCloseable lock = RWLock.read()) { 
      // Do some readin' 
     } 
     try (AutoCloseable lock = RWLock.write()) { 
      // Do some writin' 
     } 
    } 
} 
Смежные вопросы