powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / больше DCL
25 сообщений из 52, страница 2 из 3
больше DCL
    #39392333
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UsmanВ Вашем случае переменную cache необходимо сделать volatile
Еще лучше final, если потом менять не предполагается,
И HashMap заменить на ConcurrentHashMap
И вместо объектов хранить обертку позволяющую заменить себя на WeakReference
И процедуру прочистки, сначала ref на weak (по прошествии времени по установленному механизму вытеснения).
Затем и удаление ключа, если weak обнулился.
...
Рейтинг: 0 / 0
больше DCL
    #39392357
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
UsmanquestionerВ примере с вики там волатильная ссылкаВ Вашем случае переменную cache необходимо сделать volatile questionerно там и проверяется на null эта же ссылка, в нашем случае не такв этом необходимости нет, т.к. cache сразу инициализируется.questionerкорректен ли код?думаю - да, если добавить volatile .questioner
Код: java
1.
byte[] result = cache.get(input);

По поводу работы HashMap в мультипоточной среде. (см. Note that this implementation is not synchronized )

по поводу "будет работать" http://stackoverflow.com/a/33351133/2674303 Вы всё ещё уверены?

Вот почему нужен или не нужен этот volatile/final я ничего не понял. Почему "в этом необходимости" ?
...
Рейтинг: 0 / 0
больше DCL
    #39392359
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сергей АрсеньевUsmanВ Вашем случае переменную cache необходимо сделать volatile
Еще лучше final, если потом менять не предполагается,
И HashMap заменить на ConcurrentHashMap
И вместо объектов хранить обертку позволяющую заменить себя на WeakReference
И процедуру прочистки, сначала ref на weak (по прошествии времени по установленному механизму вытеснения).
Затем и удаление ключа, если weak обнулился.

Вот не знаю чего-то у меня чувство, что никакого эффекта volatile не принесёт)

Прям ConcurrentWeakHashMap описали)
...
Рейтинг: 0 / 0
больше DCL
    #39392361
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questioner,
Brian GoetzHashMap is not thread-safe. Bam, end of story.
Вам об этом уже вторую тему пишут, только Гётц достаточный авторитет?
Но про чтение это он ловко.
...
Рейтинг: 0 / 0
больше DCL
    #39392363
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowiczquestioner,
Brian GoetzHashMap is not thread-safe. Bam, end of story.
Вам об этом уже вторую тему пишут, только Гётц достаточный авторитет?
Но про чтение это он ловко.

Ну так спрашиваю не потому, что я такой любознательный. Меня лично об этом на собеседовании спрашивали. И ответ что типа не надо использовать не подготовленные мапы в однопоточной среде ибо просто не надо так делать, они задизайнены под один поток на него не подействовали. Хотел узнать что будет конкретно в каждом конкретном случае.
...
Рейтинг: 0 / 0
больше DCL
    #39392364
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerВ нашем конкретно коде такое возможно?
- Вот это код говно?
- Да, говно.
- Но почему он говно?
- Потому что, вот тут может сломаться и тут может сломаться.
- Но ведь, у в этом коде этого нет, и того тоже нет.
- А если что-то в этом коде поменять, то он сломается. Поэтому код говно.

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

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

Ну вообще наверное полезно понимать, что происходит при написании кода, на что можно полагаться, а на что нет
...
Рейтинг: 0 / 0
больше DCL
    #39392366
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerХотел узнать что будет конкретно в каждом конкретном случае.
Конкретно будет любая неведомая уита - бесконечные циклы, NPE, ненахождение значений, которые там есть и вообще любое непредсказуемое поведение, которое зависит от версии Java. Потому как Java API гарантирует определенное поведение при правильном использовании. А при не правильном использовании они никак не гарантирует что сегодня оно будет так ломаться, а завтра иначе.
...
Рейтинг: 0 / 0
больше DCL
    #39392368
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerНу вообще наверное полезно понимать, что происходит при написании кода, на что можно полагаться, а на что нет
Можно полагаться на документацию. Нельзя полагаться на то чего в документации нет.
...
Рейтинг: 0 / 0
больше DCL
    #39392370
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczquestionerХотел узнать что будет конкретно в каждом конкретном случае.
Конкретно будет любая неведомая уита - бесконечные циклы, NPE, ненахождение значений, которые там есть и вообще любое непредсказуемое поведение, которое зависит от версии Java. Потому как Java API гарантирует определенное поведение при правильном использовании. А при не правильном использовании они никак не гарантирует что сегодня оно будет так ломаться, а завтра иначе.

ну ок, в эту сторону предлагаю не копать.

Но вот в решении с ReadWriteLock надо volatile/final у поля или нет?
Если да, то почему?

Решение работоспособно вообще или нет?
...
Рейтинг: 0 / 0
больше DCL
    #39392397
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerНо вот в решении с ReadWriteLock надо volatile/final у поля или нет?
Если да, то почему?

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

в одном объекте
...
Рейтинг: 0 / 0
больше DCL
    #39392408
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
забыл никquestionerНо вот в решении с ReadWriteLock надо volatile/final у поля или нет?
Если да, то почему?

Не надо, но при условии, что доступ к этой переменной идет только в одном потоке и все доступы синхронизированы на одном локе

Код: 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
    #39392417
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerНо вот в решении с ReadWriteLock надо volatile/final у поля или нет?
Если да, то почему?

Решение работоспособно вообще или нет?
Точнее в решении с volatile/final не нужен ReadWriteLock (он дороже к тому же).
И то и другое гарантирует, что установится h-b отношение. Говорящее о том, что все что должно было быть сделано раньше в этом потоке до действия a будет видно и в других потоках если в нем увидели результат a.
Другими словами если в переменную volatile записали что-то, что должно быть по программе раньше этой записи (отработал конструктор). То другой поток получит эту ссылку только после отработавшего конструктора.
Поскольку другие потоки не увидят никаких действий, которые происходят в этом фрагменте
Код: java
1.
2.
3.
4.
5.
6.
 readLock.lock();
        try {
            result = cache.get(input);
        } finally {
            readLock.unlock();
        }


То никакого смысла в созданных h-b отношениях нет.
Вот если б new HashMap<>(); дергал readLock.lock(); тогда да.
Но на практике это увидеть не реально.
Нет - по причине HashMap.
...
Рейтинг: 0 / 0
больше DCL
    #39392421
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
package ru.sql.java;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.ArrayUtils;

public abstract class Digest {
    
    private Map<String, byte[]> cache = new HashMap<>(); // без volatile !!!

    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);
                }
            }
        } else {
            // если key == value, тогда OK
            if (!ArrayUtils.isEquals(input.getBytes(), result)) {
                System.out.printf("%s != %d%n", input, result[0]); // FAIL, если get() выдал не то, что нужно
            }
        }
        return result;
    }

    protected abstract byte[] doDigest(String input);
    
    static long key = 0;

    public static void main(String[] args) {
        Digest digest = new Digest() {
            @Override
            protected byte[] doDigest(String input) {
                return input.getBytes();
            }
        };
        
        Runnable r = () -> digest.digest(String.valueOf(++key));
        
        List<Thread> tl;
        
        int times = 5000;
        
        // выполняется put() (т.к. cache еще пуст)
        
        key = 0;
        tl = new ArrayList<>();
        for (int i = 0; i < times; i++) {
            tl.add(new Thread(r));
        }
        for (Thread t: tl) {
            t.start();
        }
        
        // теперь get() возвращает неNULLевое значение
        
        key = 0;
        tl = new ArrayList<>();
        for (int i = 0; i < times; i++) {
            tl.add(new Thread(r));
        }
        for (Thread t: tl) {
            t.start();
        }
    }
}

...
Рейтинг: 0 / 0
больше DCL
    #39392474
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сергей АрсеньевquestionerНо вот в решении с ReadWriteLock надо volatile/final у поля или нет?
Если да, то почему?

Решение работоспособно вообще или нет?
Точнее в решении с volatile/final не нужен ReadWriteLock (он дороже к тому же).
И то и другое гарантирует, что установится h-b отношение. Говорящее о том, что все что должно было быть сделано раньше в этом потоке до действия a будет видно и в других потоках если в нем увидели результат a.
Другими словами если в переменную volatile записали что-то, что должно быть по программе раньше этой записи (отработал конструктор). То другой поток получит эту ссылку только после отработавшего конструктора.
Поскольку другие потоки не увидят никаких действий, которые происходят в этом фрагменте
Код: java
1.
2.
3.
4.
5.
6.
 readLock.lock();
        try {
            result = cache.get(input);
        } finally {
            readLock.unlock();
        }


То никакого смысла в созданных h-b отношениях нет.
Вот если б new HashMap<>(); дергал readLock.lock(); тогда да.
Но на практике это увидеть не реально.
Нет - по причине HashMap.

А решение с volatile это какое точно? Код можно?

Вас не смущают параллельные чтения и записи?
...
Рейтинг: 0 / 0
больше DCL
    #39392577
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerА решение с volatile это какое точно? Код можно?

Вас не смущают параллельные чтения и записи?
Вам про Фому, Вы про Ерёму.

JIT компилятору (да и процессору если умеет) разрешен out of order execution.
Другими словами встретив
Код: java
1.
 private Map<String, byte[]> cache = new HashMap<>();


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

Для того, чтобы этого гарантированно не произошло, надо поставить барьер.
Публикация через volatile создает такой барьер.

Что касается работы с HashMap, то если закрыть все операции с ней одной блокировкой, то все пучком. Но и параллельности никакой.
Запрещать же параллельно читать из map смысла никакого при условии отсутствия модифицирующих операций это безопасно.
Разрешать же параллельно выполнять одну операцию чтения и одну операцию записи ни Вашим и ни нашим. И гарантий никаких и все выстраиваются в очередь.
...
Рейтинг: 0 / 0
больше DCL
    #39392689
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
[quot Сергей Арсеньев]questionerОни имеют право записать в переменную cache адрес отведенного под HashMap участка памяти и пойти выполнять код дальше, а конструктор отложить на потом.
Однако, если встретится обращение к экземпляру объекта то это обращение вынуждено будет подождать окончание конструктора.
Только вот другой поток про это однако ничего знать не будет. и у него метод digest() может выполнится раньше окончания конструктора.



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

Повторяю. Out of order execution. Сслыка (адрес участка памяти отведенного под объект) будет известна до вызова конструктора. Поскольку конструктор ее не меняет, то для OoOE пофигу в какой последовательности их выполнять. Ровно до чтения содержимого памяти по этому адресу. Но сам адрес записать в переменную по другому адресу можно.
Если дальше нет барьера - то другой поток может прочесть этот адрес.

Правда для достижения этого нужно добиться этой оптимизации, при этом устроить гонку и заполучить кешлайн в который попал недоинициализированный объект в кеш другого процессора на котором будет исполняться код другого потока (чтоб он и не думал читать актуальное состояние объекта). Да и еще если процы будут TSO архитектуры, они будут этому сопротивляться.
...
Рейтинг: 0 / 0
больше DCL
    #39392710
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сергей Арсеньевquestioner,

Повторяю. Out of order execution. Сслыка (адрес участка памяти отведенного под объект) будет известна до вызова конструктора. Поскольку конструктор ее не меняет, то для OoOE пофигу в какой последовательности их выполнять. Ровно до чтения содержимого памяти по этому адресу. Но сам адрес записать в переменную по другому адресу можно.
Если дальше нет барьера - то другой поток может прочесть этот адрес.

Правда для достижения этого нужно добиться этой оптимизации, при этом устроить гонку и заполучить кешлайн в который попал недоинициализированный объект в кеш другого процессора на котором будет исполняться код другого потока (чтоб он и не думал читать актуальное состояние объекта). Да и еще если процы будут TSO архитектуры, они будут этому сопротивляться.

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

напишите пример кода, пожалуйста.
...
Рейтинг: 0 / 0
больше DCL
    #39392724
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
К тому же в примере с dcl там поле статическое и его могут увидеть, это очевидно, а в нашем случае поле нестатическое
...
Рейтинг: 0 / 0
больше DCL
    #39392829
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerадрес памяти, отведенный под объект этот будет известен кому?
Кому вы захотите присвоить адрес созданного instance Вашего класса Digest, тому и будет виден.
Если он останется только в рамках одного потока, то весь разговор яйца выеденного не стоит.

Еще раз поясняю. Если этот адрес будет ссылаться на участок памяти, который будет в кеше другого процессора взятом тем ядром на момент до окончания работы конструктора и вы не попросите его инвалидировать по окончании работы конструктора, то он останется в виде как есть. То же работает и с JIT компилятором.
...
Рейтинг: 0 / 0
больше DCL
    #39392830
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerК тому же в примере с dcl там поле статическое и его могут увидеть, это очевидно, а в нашем случае поле нестатическое
А сам объект? Как его будут публиковать - гарантии есть?
...
Рейтинг: 0 / 0
больше DCL
    #39392901
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сергей Арсеньев,

Я понял кажется вас. Такая ситуация возможна только если мы теряем ссылку из конструктора?

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

Не обязательно из конструктора. Конструктор сам по себе барьера не создает.

грубо говоря
THREAD A
Код: java
1.
2.
3.
static Object myDigester;
....
myDigester= new Digestr() {...};


THREAD B
Код: java
1.
2.
3.
[SRC java]static Object myDigester;
....
if (myDigester!=null) myDigester.digest(...)


уже может создать эту ситуацию.
Код: java
1.
static volatile Object myDigester;


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


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