Эквивалент AtomicReference, но без затрат на синхронизацию - PullRequest
4 голосов
/ 01 декабря 2011

Что эквивалентно:

AtomicReference<SomeClass> ref = new AtomicReference<SomeClass>( ... );

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

Я смотрел на классы, расширяющие абстрактный класс Reference , но я немного потерян среди всех вариантов.

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

Ответы [ 8 ]

5 голосов
/ 01 декабря 2011

Если вам нужна ссылка без безопасности потока, вы можете использовать массив из одного.

MyObject[] ref = { new MyObject() };
MyObject mo = ref[0];
ref[0] = n;
3 голосов
/ 01 декабря 2011

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

Вы не должны создавать класс StrongReference (потому что это было бы глупо), а демонстрировать его

public class StrongReference{
  Object refernece;

  public void set(Object ref){
    this.reference =ref;
  }
  public Object get(){
    return this.reference;
  }

}
2 голосов
/ 01 декабря 2011

Я думаю, все, что вы хотите, это:

public class MyReference<T>{
    T reference;

    public void set(T ref){
      this.reference =ref;
    }
    public T get(){
      return this.reference;
    }

  }

Возможно, вы захотите добавить делегирующие функции equals (), hashcode () и toString ().

2 голосов
/ 01 декабря 2011

Если вы все еще хотите использовать AtomicReference, но не хотите нести стоимость энергозависимой записи, вы можете использовать lazySet

Запись не создает барьер памяти, который делает нормальная энергозависимая запись, но метод get по-прежнему вызывает энергозависимую нагрузку (что относительно дешево)

AtomicReference<SomeClass> ref = new AtomicReference<SomeClass>();

ref.lazySet(someClass);
2 голосов
/ 01 декабря 2011

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

0 голосов
/ 19 июля 2018

Если ваше значение является неизменным, java.util.Optional выглядит как отличный вариант.

0 голосов
/ 01 декабря 2011

все предоставленные классы, расширяющие Reference, имеют некоторые специальные функциональные возможности, от атомарного CaS до разрешения сбора ссылочного объекта, хотя ссылка на объект все еще существует

вы можете создать свой собственный StringReference, как объяснил Джон Винт (или использовать массив с длиной == 1), но для этого не так много вариантов использования

0 голосов
/ 01 декабря 2011

Нет затрат на синхронизацию с AtomicReference.Из описания java.util.concurrent.atomic пакета:

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

РЕДАКТИРОВАТЬ Судя по вашим комментариям к исходному сообщению, кажется, что вы использовали термин "стоимость синхронизации" нестандартным образом для обозначения очистки потока локального потока в целом.На большинстве архитектур чтение volatile почти так же дешево, как чтение энергонезависимого значения.Любое обновление разделяемой переменной потребует очистки кеша хотя бы этой переменной (если только вы не собираетесь полностью отменить локальные кеши потоков).Нет ничего дешевле (с точки зрения производительности), чем классы в java.util.concurrent.atomic.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...