Получить массив из AtomicLongArray - PullRequest
3 голосов
/ 23 февраля 2012

Используя Java 1.6 и AtomicLongArray, я бы хотел «скопировать» оригинальный AtomicLongArray в новый. Существует конструктор, который принимает массив (AtomicLongArray (long [])), поэтому я подумал, что могу просто получить массив из исходного и передать его конструктору.

К сожалению, фактическое значение long [] в массиве AtomicLongArray является закрытым, и, похоже, для него нет получателей. Есть ли способ сделать это, то есть скопировать значения из одного AtomicLongArray в другой? Я не могу создать свой собственный класс на основе этого класса, так как класс sun.misc.Unsafe мне недоступен.

Это необходимо, потому что я собираюсь перебирать значения, и я не хочу, чтобы они изменялись другим потоком во время итерации. Поэтому я подумал, что смогу сделать копию и использовать ее для итерации ...

Спасибо! Phillip

Ответы [ 2 ]

4 голосов
/ 23 февраля 2012

Я подозреваю, что вам нужно создать свой собственный long[] и сначала заполнить его, или просто перебрать оригинал:

AtomicLongArray copy = new AtomicLongArray(original.length());
for (int i = 0; i < copy.length(); i++)
{
    copy.set(i, original.get(i));
}

Обратите внимание, что хотя каждая отдельная операция в AtomicLongArray является атомарной, существует никаких массовых операций - поэтому нет способа получить «снимок» всего массива в момент времени T. Если вы хотите, чтобы Такое поведение, я думаю, вам нужно использовать синхронизацию.

2 голосов
/ 23 февраля 2012

Эта структура данных позволяет одновременно обновлять отдельные записи в коллекции. Общая блокировка отсутствует, поэтому вы не можете предотвратить изменение потока другим потоком во время итерации по нему.

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

long[] copy = new long[original.length()];
boolean changed = true;
// repeat until we get an unchanged copy.
while(true) {
    for (int i = 0; i < copy.length(); i++) {
        long l = original.get(i);
        changed |= copy[i] != l;
        copy[i] = l;
    }
    if (!changed) break;
    changed = false;
}

Это не совсем безопасно, но может быть достаточно для того, что вам нужно.

...