2014-02-26 2 views
0

Ситуация такова: я реализую CharSequence над большими текстовыми файлами (чтобы иметь возможность передать их Pattern).Как подождать, одновременно, что целое число достигает определенного значения?

У меня есть список CharWindow с, что является довольно простой класс:

public final class CharWindow 
{ 
    private final long fileOffset; 
    private final long mappingLength; 
    private final int charOffset; 
    private final int charLength; 
    // Constructor, methods, etc etc 
} 

В отдельном классе, я генерировать экземпляры CharWindow с, начиная с начала файла до конца; во время этого процесса я увеличиваю AtomicInteger (назовем его totalChars), что является общим количеством символов в файле.

Теперь представим себе, что вызывающий абонент называет .charAt(25030) на CharSequence; но в то время класс читателя/декодера только завершил (успешно) декодирование 10430 символов; и он продолжается: 15640, 21032, 25602 - при каждом обновлении totalChars. И другие абоненты могут звонить .charAt() с различными аргументами.

Будешь говорить, что класс чтения/декодер имеет (потокобезопасный, одновременно дружественный) метод имеет .needChars() с междунар в качестве аргумента и коды .charAt() в CharSequence реализации гласит:

@Override 
public char charAt(final int index) 
{ 
    readerDecoder.needChars(index); 
    // do whatever is needed to read the chars 
} 

Есть ли способ реализации .needChars(), чтобы он блокировал ожидания totalChars, чтобы достичь соответствующего значения?

ответ

3

я реализовал нечто подобное с использованием PriorityBlockingQueue и CountDownLatches. Идея состоит в том, чтобы связать в вашем случае требуемое количество символов с защелкой, которую можно ожидать, например.

public class RequireCharacters implements Comparable<RequireCharacters> { 
    public final long required; 
    public final CountDownLatch latch = new CountDownLatch(1); 

    /* ctor etc. */ 

    public int compareTo(RequireCharacters other) { return Long.compare(this.required, other.required); } 
} 

Тогда вы можете использовать один PriorityBlockingQueue для управления потоками, которые ждут большего количества символов. Если поток в needChars() обнаруживает, что еще недостаточно обработанных символов, он отправляет объект RequireCharacters в очередь и ожидает содержащуюся защелку. Всякий раз, когда количество символов увеличивается, возрастающий поток должен проверять очередь. Когда упорядоченные элементы упорядочены, он может заглядывать и освобождать ожидающие потоки, пока больше символов не будет обработано, чтобы удовлетворить официанта.

Есть небольшая вероятность, что нить наблюдает за недостаточным количеством символов, но отправляет объект RequireCharacters после того, как другой поток увеличил количество символов. Либо синхронизируйте соответствующим образом, либо перепроверьте счет после отправки в очередь.

+0

Очень интересно! Я пойду на это ... – fge

+0

Я забыл добавить его, но я думаю, что время ожидания должно быть значительным, чтобы оправдать накладные расходы такой синхронизации. Если среднее время ожидания довольно короткое, вам может быть лучше, просто ожив на AtomicLong (возможно, добавьте Thread.Выход() с). – Pyranja

+0

Ну, это зависит от начального размера файла ... Если это несколько сотен мегабайт, может потребоваться некоторое время, чтобы проверить, что все это текст/вычисление смещений/и т. Д. Кроме того, я буду сокращать, если нет необходимости ждать, конечно, что в конечном итоге будет иметь место для всех абонентов. – fge

0

Я бы поставил это в комментарии, но не имел репутации.

Попробуйте это - Java: How to wake thread on demand?

Вы должны быть в состоянии контролировать значение затем просыпаются нить для выполнения любой функ вам нужно.

редактировать или просто ждать, уведомив другую нить, когда значение попадает правильное количество How to use wait and notify in Java?

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