Шаблон синхронизации - PullRequest
       1

Шаблон синхронизации

5 голосов
/ 03 февраля 2012

У меня есть класс с именем «Channel», в котором определены два метода:

class Channel {

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

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

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

Ответы [ 2 ]

8 голосов
/ 03 февраля 2012

Используйте 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 голос
/ 04 февраля 2012

Для забавы, вот реализация, использующая новую функцию пробного использования ресурсов Java 7.

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'
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...