Лучше всего приблизьтесь для использования в Java 6 для Списка, получаемого доступ одновременно

Одно из моих изображений не имело прозрачности, в этом была проблема.

7
задан Herman Lintvelt 16 October 2008 в 10:24
поделиться

5 ответов

Необходимо ли использовать последовательный список? Если структура типа карты является более соответствующей, можно использовать a ConcurrentHashMap. Со списком, a ReadWriteLock вероятно, самый эффективный путь.

Редактирование для отражения редактирования OP: Двоичный поиск на порядке вставки? Вы храните метку времени и использование это для сравнения в Вашем двоичном поиске? Если так, Вы можете использовать метку времени в качестве ключа, и ConcurrentSkipListMap как контейнер (который поддерживает ключевой порядок).

3
ответ дан 7 December 2019 в 07:52
поделиться

Можно использовать обертку, которая реализует синхронизацию:

import java.util.Collections;
import java.util.ArrayList;

ArrayList list = new ArrayList();
List syncList = Collections.synchronizedList(list);

// make sure you only use syncList for your future calls... 

Это - легкое решение. Я попробовал бы это прежде, чем обратиться к более сложным решениям.

1
ответ дан 7 December 2019 в 07:52
поделиться

Что делают потоки чтения? Если они выполняют итерации по списку, то действительно необходимо удостовериться, что никто не касается списка во время всего итеративного процесса, иначе Вы могли получить очень нечетные результаты.

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

1
ответ дан 7 December 2019 в 07:52
поделиться

Я не знаю, является ли это возможным решением для проблемы, но... имеет смысл мне использовать Менеджер базы данных, чтобы содержать тот огромный объем данных и позволить ему справиться с транзакциями

1
ответ дан 7 December 2019 в 07:52
поделиться

Я предложение второго Telcontar базы данных, так как они на самом деле разработаны для управления этим масштабом данных и согласования между потоками, в то время как наборы в оперативной памяти не.

Вы говорите, что данные находятся на базе данных по серверу, и локальный список на клиентах ради пользовательского интерфейса. Вы не должны должны быть сохранять все 100 000 объектов на клиенте сразу или выполнять такие сложные редактирования на нем. Мне кажется, что то, что Вы хотите на клиенте, является легким кэшем на базу данных.

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

Да, это - вполне сложное решение. Компоненты его:

  • Протокол для загрузки диапазона данных, говорят объекты 478 712 - 478 901, а не все это
  • Протокол для получения обновлений об измененных данных
  • Класс кэша, который хранит объекты их известным индексом на сервере
  • Поток, принадлежащий тому кэшу, который связался с сервером. Это - единственный поток, который пишет в сам набор
  • Поток, принадлежащий тому кэшу, который обрабатывает обратные вызовы, когда данные получены
  • Интерфейс, который компоненты UI реализуют, чтобы позволить им получать данные, когда это было загружено

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

class ServerCacheViewThingy {
    private static final int ACCEPTABLE_SIZE = 500;
    private int viewStart, viewLength;
    final Map<Integer, Record> items
            = new HashMap<Integer, Record>(1000);
    final ConcurrentLinkedQueue<Callback> callbackQueue
            = new ConcurrentLinkedQueue<Callback>();

    public void getRecords (int start, int length, ViewReciever reciever) {
        // remember the current view, to prevent records within
        // this view from being accidentally pruned.
        viewStart = start;
        viewLenght = length;

        // if the selected area is not already loaded, send a request
        // to load that area
        if (!rangeLoaded(start, length))
            addLoadRequest(start, length);

        // add the reciever to the queue, so it will be processed
        // when the data has arrived
        if (reciever != null)
            callbackQueue.add(new Callback(start, length, reciever));
    }

    class Callback {
        int start;
        int length;
        ViewReciever reciever;
        ...
    }

    class EditorThread extends Thread {

        private void prune () {
            if (items.size() <= ACCEPTABLE_SIZE)
                return;
            for (Map.Entry<Integer, Record> entry : items.entrySet()) {
                int position = entry.key();
                // if the position is outside the current view,
                // remove that item from the cache
                ...
            }
        }

        private void markDirty (int from) { ... }

        ....
    }

    class CallbackThread extends Thread {
        public void notifyCallback (Callback callback);
        private void processCallback (Callback) {
            readRecords
        }
    }
}

interface ViewReciever {
    void recieveData (int viewStart, Record[] records);
    void recieveTimeout ();
}

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

1
ответ дан 7 December 2019 в 07:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: