Синхронизация очереди FIFO

Следует ли синхронизировать очередь FIFO, если есть только один читатель и один писатель?


person Arthur    schedule 12.01.2009    source источник


Ответы (5)


Что вы имеете в виду под «синхронизированным»? Если ваш читатель и писатель находятся в разных потоках, вы хотите, чтобы FIFO обрабатывал параллелизм «правильно», включая такие детали, как:

  • правильное использование FIFO API никогда не должно приводить к повреждению структур данных
  • правильное использование FIFO API не должно вызывать тупик (хотя должен быть механизм, позволяющий читателю ждать, пока будет что читать)
  • объекты, считываемые из FIFO, должны быть теми же объектами, в том же порядке, записанными в FIFO (не должно быть пропущенных объектов или измененного порядка)
  • должно быть ограниченное время (хотелось бы надеяться!) между тем, когда писатель помещает что-то в FIFO, и тем, когда это становится доступным для читателя.

В мире Java есть хорошая книга по этому поводу: Java Concurrency In Практика. Есть несколько способов реализовать FIFO, который правильно обрабатывает параллелизм. Самыми простыми реализациями являются блокирующие, в более сложных используются неблокирующие алгоритмы, основанные на инструкциях сравнения и замены, которые сегодня встречаются на большинстве процессоров.

person Jason S    schedule 12.01.2009

Да, если читатель и писатель взаимодействуют с очередью FIFO из разных потоков.

person ng.    schedule 12.01.2009

В зависимости от реализации, но скорее всего. Вы не хотите, чтобы читатель читал частично записанные данные.

person Domchi    schedule 12.01.2009

Да, если в документации явно не указано иное.

(Можно реализовать специализированный FIFO, который не требует синхронизации, если есть только один читатель и один поток записи, например, в Windows с использованием функций InterlockedXXX.)

person oefe    schedule 12.01.2009

Попробуйте этот код для одновременного использования FIFO:

public class MyObjectQueue {

private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

private static final ReadLock readLock;

private static final WriteLock writeLock;

private static final LinkedList<MyObject> objects;

static {
    readLock = lock.readLock();
    writeLock = lock.writeLock();
    objects = new LinkedList<MyObject>();
}

public static boolean put(MyObject p) {
    writeLock.lock();
    try {
        objects.push(p);            
        return objects.contains(p);
    } finally {
        writeLock.unlock();
    }
}

public static boolean remove(MyObject p) {
    writeLock.lock();
    try {
        return objects.remove(p);           
    } finally {
        writeLock.unlock();
    }
}

public static boolean contains(MyObject p) {
    readLock.lock();
    try {
        return objects.contains(p);         
    } finally {
        readLock.unlock();
    }
}   

public MyObject get() {
    MyObject o = null;
    writeLock.lock();
    try {
        o = objects.getLast();
    } catch (NoSuchElementException nse) {
        //list is empty
    } finally {
        writeLock.unlock();
    }
    return o;
}

}

person Paul Gregoire    schedule 05.12.2009