powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / больше DCL
25 сообщений из 52, страница 1 из 3
больше DCL
    #39391527
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Корректен ли код?
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
import java.util.HashMap;
import java.util.Map;

// REVIEW
public abstract class Digest {
    private Map<String, byte[]> cache = new HashMap<>();

    public byte[] digest(String input) {
        byte[] result = cache.get(input);
        if (result == null) {
            synchronized (cache) {
                result = cache.get(input);
                if (result == null) {
                    result = doDigest(input);
                    cache.put(input, result);
                }
            }
        }
        return result;
    }

    protected abstract byte[] doDigest(String input);
}



корректен ли код?

Если нет, то поможет ли volatile пометить cache ?
Просто никогда не думал насчёт того, что если мы видим корректное visibility ссылки на объект - распространяется ли это на те объекты, на которые он ссылается(композирует, аггрегирует)?
...
Рейтинг: 0 / 0
больше DCL
    #39391544
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerкорректен ли код?

Не совсем. Чтение может происходит параллельно с записью, что чревато.

questionerЕсли нет, то поможет ли volatile пометить cache ?

Устал уже что ли? volatile здесь только влияет на ссылку cache. А ссылка эта нигде в коде не меняется. Можно final воткнуть.

questionerПросто никогда не думал насчёт того, что если мы видим корректное visibility ссылки на объект - распространяется ли это на те объекты, на которые он ссылается(композирует, аггрегирует)?
Нет, не распространяется.
...
Рейтинг: 0 / 0
больше DCL
    #39391654
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowiczquestionerкорректен ли код?

Не совсем. Чтение может происходит параллельно с записью, что чревато.

Что прочитаем что-то не то?
Можно сказать что-то более конкретное, чем непредсказуемое поведение?

BlazkowiczУстал уже что ли? volatile здесь только влияет на ссылку cache. А ссылка эта нигде в коде не меняется. Можно final воткнуть.

Я понимаю, что final он же volatile. Но конкретно в этом коде это повлияет разве как-то? или только на возможное расширение класса. Ну то есть разве может кто-то увидеть null ссылку на cache ?


Правильно ли, что если не использовать другую коллекцию, то можно использовать например ReadWriteLock?
...
Рейтинг: 0 / 0
больше DCL
    #39391696
Фотография fixxer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это не вопрос ли из анкеты в ваканси Java Developer в Яндекс?
...
Рейтинг: 0 / 0
больше DCL
    #39391806
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
fixxerЭто не вопрос ли из анкеты в ваканси Java Developer в Яндекс?

Я слышал кстати уже такую версию. Возможно собеседующий ходил в яндекс когда-то)
...
Рейтинг: 0 / 0
больше DCL
    #39391831
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
немного перефразирую второй вопрос

если мы не используем volatile/final могут ли быть проблемы с видимостью cache ?

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

а использовать метод мы можем только после того ссылка создалась.

Есть на такой случай HB ?
...
Рейтинг: 0 / 0
больше DCL
    #39391901
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questioner,

Тут две проблемы.
1. При удачном стечении обстоятельств, после публикации экземпляра наследника можно схватить NPE на том, что cache все еще null, а digest уже вызвали.
2. Недавно пролетал опрос на то, что бывает с HashMap при многопоточном использовании.
...
Рейтинг: 0 / 0
больше DCL
    #39391913
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сергей Арсеньевquestioner,

Тут две проблемы.
1. При удачном стечении обстоятельств, после публикации экземпляра наследника можно схватить NPE на том, что cache все еще null, а digest уже вызвали.
2. Недавно пролетал опрос на то, что бывает с HashMap при многопоточном использовании.


volatile я так понимаю спасёт нас от 1 пункта.

по поводу второго мы там ни о чем не договорились, отличного от того, что поведение непредсказуемо
...
Рейтинг: 0 / 0
больше DCL
    #39391927
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerпо поводу второго мы там ни о чем не договорились, отличного от того, что поведение непредсказуемо
А этого достаточно, чтоб так не делать.
...
Рейтинг: 0 / 0
больше DCL
    #39391984
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сергей Арсеньевquestionerпо поводу второго мы там ни о чем не договорились, отличного от того, что поведение непредсказуемо
А этого достаточно, чтоб так не делать.

Пусть я собеседую:

Ок, разобрались, что лучше использовать CHM, но допустим по каким-то причинам мы этого сделать не можем, как сделать корректным без CHM ?
...
Рейтинг: 0 / 0
больше DCL
    #39391999
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerПравильно ли, что если не использовать другую коллекцию, то можно использовать например ReadWriteLock?
Да.
...
Рейтинг: 0 / 0
больше DCL
    #39392002
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerесли мы не используем volatile/final могут ли быть проблемы с видимостью cache ?

Надо освежить что там в JMM пишут по поводу конструктора и безопасных публикаций. То есть, если у тебя из конструктора, утекает ссылка на объект, да ещё и в другой поток, то он может увидеть null.

questionerведь получается, что мы сетаем его в конструкторе(думаю это эквивалентно текущей записи).

Да, но вопрос в том, чем ты гарантируешь что другой поток не увидит объект во время выполнения конструктора?

questionerа использовать метод мы можем только после того ссылка создалась.

Тут чувствуется некоторое непонимание в вопросе. Нет никакого "ссылка создалась". Ссылку на объект можно получить до того как закончит выполнение конструктор.
...
Рейтинг: 0 / 0
больше DCL
    #39392005
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей Арсеньев 1. При удачном стечении обстоятельств, после публикации экземпляра наследника можно схватить NPE на том, что cache все еще null, а digest уже вызвали.

Из наследника можно получить null даже если там будет final. Эта другая проблема.

Сергей Арсеньев2. Недавно пролетал опрос на то, что бывает с HashMap при многопоточном использовании.
Так он же и спрашивал. Теперь решил по второму кругу.
...
Рейтинг: 0 / 0
больше DCL
    #39392006
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczИз наследника можно получить null даже если там будет final. Эта другая проблема.

Не-е, гоню. Это в родительском классе можно получить null в final поле. В любом случае родители и наследники, это не единственный способ сделать публикацию объекта не безопасной.
...
Рейтинг: 0 / 0
больше DCL
    #39392028
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczquestionerПравильно ли, что если не использовать другую коллекцию, то можно использовать например ReadWriteLock?
Да.

прошу оценить критическим взглядом:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
public abstract class Digest {

    private final ReadWriteLock rwl = new ReentrantReadWriteLock();
    private final Lock readLock = rwl.readLock();
    private final Lock writeLock = rwl.writeLock();

    private Map<String, byte[]> cache = new HashMap<>();

    public byte[] digest(String input) {
        byte[] result = null;
        readLock.lock();
        try {
            result = cache.get(input);
        } finally {
            readLock.unlock();
        }
        if (result == null) {
            writeLock.lock();
            try {
                result = cache.get(input);
                if (result == null) {
                    result = doDigest(input);
                    cache.put(input, result);
                }
            } finally {
                writeLock.unlock();
            }
        }

        return result;
    }

    protected abstract byte[] doDigest(String input);
}
...
Рейтинг: 0 / 0
больше DCL
    #39392035
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowiczquestionerесли мы не используем volatile/final могут ли быть проблемы с видимостью cache ?

Надо освежить что там в JMM пишут по поводу конструктора и безопасных публикаций. То есть, если у тебя из конструктора, утекает ссылка на объект, да ещё и в другой поток, то он может увидеть null.

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

Да, но вопрос в том, чем ты гарантируешь что другой поток не увидит объект во время выполнения конструктора?


А как можно запустить конструирование одного и того же объекта из разных тредов?
Я на самом деле не представляю другого способа кроме как утекания ссылки из конструктора. В нашем конкретно коде такое возможно?

questionerа использовать метод мы можем только после того ссылка создалась.

BlazkowiczТут чувствуется некоторое непонимание в вопросе. Нет никакого "ссылка создалась". Ссылку на объект можно получить до того как закончит выполнение конструктор.


Кроме утекания из конструктора ещё есть какие-то варианты такого?
...
Рейтинг: 0 / 0
больше DCL
    #39392044
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczBlazkowiczИз наследника можно получить null даже если там будет final. Эта другая проблема.

Не-е, гоню. Это в родительском классе можно получить null в final поле. В любом случае родители и наследники, это не единственный способ сделать публикацию объекта не безопасной.

Надо бы отдельно это обсудить) может ссылку какую выдадите?
...
Рейтинг: 0 / 0
больше DCL
    #39392111
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz В любом случае родители и наследники, это не единственный способ сделать публикацию объекта не безопасной.
Наследник был упомянут, токма по причине абстрактности класса.
final как бы гарантирует что ссылка на экземпляр раньше времени (заполнения final) не утечет.
Другое дело, что HashMap не очень то хороший cache, особенно в свете многопоточности.
Есть же всякие в Guave и у Apache реализации.
...
Рейтинг: 0 / 0
больше DCL
    #39392149
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сергей АрсеньевBlazkowicz В любом случае родители и наследники, это не единственный способ сделать публикацию объекта не безопасной.
Наследник был упомянут, токма по причине абстрактности класса.
final как бы гарантирует что ссылка на экземпляр раньше времени (заполнения final) не утечет.
Другое дело, что HashMap не очень то хороший cache, особенно в свете многопоточности.
Есть же всякие в Guave и у Apache реализации.

Приватное поле недоступно наследнику же.

Не понял как final с утеканием связан. Может пример?


Ну это понятно. что есть нормальные протестированные кеши, это не практический вопрос, исключительно в образовательных целях рассматривается
...
Рейтинг: 0 / 0
больше DCL
    #39392187
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerНу это понятно. что есть нормальные протестированные кеши, это не практический вопрос, исключительно в образовательных целях рассматривается
Чисто в образовательных целях надо читать Java Memory Model. Там есть ссылочка на документик в котором описывается как jvm инициализирует экземпляр класса в каком порядке и когда отпускается блокировочка не позволяющая увидеть ссылку раньше некоторого события. Так вот final поля они до, а не final и цепочка конструкторов после.
В связи с чем есть теоретическая возможность (и та скорее всего не для x86) что кто-то увидит ссылку на экземпляр наследника, когда cache еще не до конца проинициализирован. После чего вызов instance.digest(), который у Вас первым делом пытался сделать cache.get() будет слегка удивлен.

Если я правильно понимаю (хотя скорее ошибаюсь), то и вызов readLock.lock(); из другого потока (не того, в котором происходила инициализация instance) не устанавливает h-b грань (ибо в нем инициализации то не происходило).
...
Рейтинг: 0 / 0
больше DCL
    #39392211
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
больше DCL
    #39392275
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Usmanquestioner,

https://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java

Это к чему вообще?
...
Рейтинг: 0 / 0
больше DCL
    #39392281
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerЭто к чему вообще?К 1-му посту
...
Рейтинг: 0 / 0
больше DCL
    #39392303
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
UsmanquestionerЭто к чему вообще?К 1-му посту

Если честно, я не понял, проясните.

В примере с вики там волатильная ссылка, но там и проверяется на null эта же ссылка, в нашем случае не так
...
Рейтинг: 0 / 0
больше DCL
    #39392315
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerВ примере с вики там волатильная ссылкаВ Вашем случае переменную cache необходимо сделать volatile questionerно там и проверяется на null эта же ссылка, в нашем случае не такв этом необходимости нет, т.к. cache сразу инициализируется.questionerкорректен ли код?думаю - да, если добавить volatile .questioner
Код: java
1.
byte[] result = cache.get(input);

По поводу работы HashMap в мультипоточной среде. (см. Note that this implementation is not synchronized )
...
Рейтинг: 0 / 0
25 сообщений из 52, страница 1 из 3
Форумы / Java [игнор отключен] [закрыт для гостей] / больше DCL
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]