Могу ли я переопределить объект с помощью sun.misc.Unsafe? - PullRequest
9 голосов
/ 18 мая 2011

Могу ли я переопределить один объект другим, если они являются экземплярами одного и того же класса, их размер одинаков, используя sun.misc.Unsafe?

редактирование: Под «переопределением» я подразумеваю «удалить» первый объект, муравей, чтобы заполнить память вторым. Возможно ли это?

1 Ответ

9 голосов
/ 21 мая 2011

Под «переопределением» я подразумеваю «удалить» первый объект, муравей, чтобы заполнить память вторым.Возможно ли это?

Да и нет.

Да - Если вы выделите некоторую память с помощью Unsafe и напишите long , тогданапишите еще один длинный (например), тогда да, вы удалили первый объект и наполнили память вторым объектом.Это похоже на то, что вы можете сделать с ByteBuffer .Конечно, long - это примитивный тип, поэтому, вероятно, это не то, что вы подразумеваете под «объектом».

Java позволяет это, поскольку имеет контроль над выделенной памятью.

Нет - Java работает со ссылками на объекты и предоставляет только ссылки на эти объекты.Более того, он имеет тенденцию перемещать объекты в памяти (т. Е. Для сбора мусора).

Невозможно получить «физический адрес» и переместить содержимое памяти с одного адреса объекта на другой, если это то, что выпытаются.Более того, вы не можете «удалить» объект, потому что на него могут ссылаться из других частей кода.

Однако всегда есть возможность иметь ссылку A на другой объект B вместо objectA с помощью A = objectB; Вы даже можете сделать это атомарным с помощью Unsafe.compareAndSwapObject(...).

Обходной путь - Теперь давайте представим, что ссылки A1, A2, A3 указывают на один и тот же объект A.Если вы хотите, чтобы все они внезапно указывали на objectB, вы не можете использовать Unsafe.compareAndSwapObject(...), потому что только A1 будет указывать на objectB, в то время как A2 и A3 по-прежнему будут указывать на objectA.Он не был бы атомарным.

Существует обходной путь:

public class AtomicReferenceChange {

    public static Object myReference = new Object();

    public static void changeObject(Object newObject) {
        myReference = newObject;
    }

    public static void main(String[] args) {

        System.out.println(AtomicReferenceChange.myReference);
        AtomicReferenceChange.changeObject("333");
        System.out.println(AtomicReferenceChange.myReference);

    }

}

Вместо нескольких ссылок на один и тот же объект, вы можете определить общедоступную статическую ссылку и использовать свой код * 1035.* везде.Если вы хотите изменить ссылочный объект атомарно, используйте статический метод changeObject(...).

...