Size: a a a

2020 August 27

DB

Dmitry Baynak in pro.jvm
может хранить общую ConcurrentHashMap из Key -> CompletableFuture и сабмиттить их на какой-нибудь ForkJoinPool (если вычисления неблокирующие; или просто на пул, если блокирующие)
источник

SK

Sergey Kapralov in pro.jvm
Gennady Lebedev
> Если не в многопоточную коллекцию, то куда мемоизировать?

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

Хорошо. А как бы ваш вариант выглядел? Можете ченить псевдокодом накидать, если не сложно?
источник

DB

Dmitry Baynak in pro.jvm
Gennady Lebedev
> Если не в многопоточную коллекцию, то куда мемоизировать?

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

не очень понятно как стримы без хранилища решают задачу ^
источник

SK

Sergey Kapralov in pro.jvm
Dmitry Baynak
я так понял что тут нужно некоторое вычисление, задаваемое некоторым уникальным для этого вычисления ключом, посчитать единожды и не считать больше никогда
некоторые вычисления, при этом, могут зависеть от вычислений по другому ключу
может как сначала прийти запрос по ключу, вычисление которого не зависит от других ключей, а может прийти запрос по другому ключу, вычисление которого зависит от других ключей, а могут прийти запросы конкуррентно

не очень понятно как стримы без хранилища решают задачу ^
Вот — да
источник

DB

Dmitry Baynak in pro.jvm
Dmitry Baynak
может хранить общую ConcurrentHashMap из Key -> CompletableFuture и сабмиттить их на какой-нибудь ForkJoinPool (если вычисления неблокирующие; или просто на пул, если блокирующие)
пришла задача по ключу в какой-то тред - тред через computeIfAbsent на CHM либо создает CompletableFuture, либо получает уже известную, дальше await'ит результата
если нужно дождаться что-то другое, аналогично - или через computeIfAbsent создаем, или получаем уже созданный инстанс CompletableFuture (или как вычисляющийся, или как уже вычислившийся) и await'имся на ней (или на них, если А1 и А2)
CompletableFuture для 1 ключа существует всегда одно, эта штука хранит и значение после вычисления
источник

N

Nick in pro.jvm
Sergey Kapralov
Всем привет.

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

Дилемму, с которой я столкнулся, можно описать следующим гистом: https://gist.github.com/skapral/60c041771bf633cbe0befa009be82db1. В реале все вышло несколько сложнее, но гист передает суть.

Есть вычисление B, результат которого зависит от двух A. И B, и А должны быть мемоизированны при первом обращении, и должна быть гарантия что вычисление каждого из doHeavyLifting методов происходит не более одного раза, вне зависимости от того, где и сколько раз их вызвали. При этом клиентская сторона может потенциально вызвать их в рандомном порядке и конкуррентно (сэмулированно в мэйне). Если раннать мэйн из гиста, он будет виснуть с некоторой вероятностью (если B пойдет вычисляться раньше чем обе A, будет дэдлок на ConcurrentHashMapе, даже если тред один).

То что нельзя вкладывать computeIfAbsentы --- я в курсе, вопрос не об этом, в примере вложенные компуты присутствуют только для иллюстрации проблемы. Вопрос в альтернативе.

На данный момент решение видится таким образом: https://gist.github.com/skapral/8545692990383adad26596b2874e6098.

Нет ли каких либо косяков? Можно ли считать memoizedCalculation потокобезопасным? Может можно было решить проще? Я что-то упускаю?
вам обязательно сразу считать а не по требованию?
источник

А

Артём Курилко... in pro.jvm
Всем привет, есть рабочая программа на виндовс, и я её перенес на убунту, одна реализация выполнения http запросов там не работает и я не понимаю в чем проблема
источник

А

Артём Курилко... in pro.jvm
Эта реализация работает на ubuntu
URL url = new URL("https://api.hitbtc.com/api/2/order?symbol=" + CURRENCY_PAIR + "&limit=50");
HttpURLConnection connection = getConnectionWithProperties(url, method);
источник

А

Артём Курилко... in pro.jvm
Эта реализация не работает на ubuntu
command = "curl -X GET \"https://api.hitbtc.com/api/2/public/trades/BTCUSD?sort=DESC&by=timestamp&limit=100";
process = Runtime.getRuntime().exec(command);

BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream()));
String stream = output.readLine();

JSONArray ordersList = new JSONArray(stream);
источник

А

Артём Курилко... in pro.jvm
Артём Курилко
Эта реализация не работает на ubuntu
command = "curl -X GET \"https://api.hitbtc.com/api/2/public/trades/BTCUSD?sort=DESC&by=timestamp&limit=100";
process = Runtime.getRuntime().exec(command);

BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream()));
String stream = output.readLine();

JSONArray ordersList = new JSONArray(stream);
это её вывод <!doctype html>
источник

А

Артём Курилко... in pro.jvm
я понимаю что через curl никто не делает, это пока не главное, curl на убунту работает
источник

А

Артём Курилко... in pro.jvm
Это потому что убунту не поддерживает работу с BufferedReader или что?
источник

SK

Sergey Kapralov in pro.jvm
Nick
вам обязательно сразу считать а не по требованию?
Не понял вопрос.
источник

N

Nick in pro.jvm
Артём Курилко
Эта реализация не работает на ubuntu
command = "curl -X GET \"https://api.hitbtc.com/api/2/public/trades/BTCUSD?sort=DESC&by=timestamp&limit=100";
process = Runtime.getRuntime().exec(command);

BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream()));
String stream = output.readLine();

JSONArray ordersList = new JSONArray(stream);
кавычку потерял в команде курла
источник

N

Nick in pro.jvm
Sergey Kapralov
Не понял вопрос.
у вас в мейне сразу три потока стартуют, но результаты А не нужны пока не запустится Б
источник

А

Артём Курилко... in pro.jvm
Nick
кавычку потерял в команде курла
это я случайно обрезал когда редактировал для этой группы
источник

А

Артём Курилко... in pro.jvm
Sergey Kapralov
Не понял вопрос.
хочу узнать что именно из второй реализации не поддерживает убунту, или это моя ошибка в коде
источник

SK

Sergey Kapralov in pro.jvm
Nick
у вас в мейне сразу три потока стартуют, но результаты А не нужны пока не запустится Б
Это условность. Этим я хотел просто проиллюстрировать, что порядок заранее неизвестен, что любой тред, в любое время, любое количество раз может дернуть как A так и B.
источник

N

Nick in pro.jvm
Артём Курилко
хочу узнать что именно из второй реализации не поддерживает убунту, или это моя ошибка в коде
java это же про write once, run everywhere - пока все написано на чистой жабе можно где угодно гонять между любыми платформами (за редким исключением)
источник

AS

Alexandr Saperov in pro.jvm
Sergey Kapralov
Всем привет.

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

Дилемму, с которой я столкнулся, можно описать следующим гистом: https://gist.github.com/skapral/60c041771bf633cbe0befa009be82db1. В реале все вышло несколько сложнее, но гист передает суть.

Есть вычисление B, результат которого зависит от двух A. И B, и А должны быть мемоизированны при первом обращении, и должна быть гарантия что вычисление каждого из doHeavyLifting методов происходит не более одного раза, вне зависимости от того, где и сколько раз их вызвали. При этом клиентская сторона может потенциально вызвать их в рандомном порядке и конкуррентно (сэмулированно в мэйне). Если раннать мэйн из гиста, он будет виснуть с некоторой вероятностью (если B пойдет вычисляться раньше чем обе A, будет дэдлок на ConcurrentHashMapе, даже если тред один).

То что нельзя вкладывать computeIfAbsentы --- я в курсе, вопрос не об этом, в примере вложенные компуты присутствуют только для иллюстрации проблемы. Вопрос в альтернативе.

На данный момент решение видится таким образом: https://gist.github.com/skapral/8545692990383adad26596b2874e6098.

Нет ли каких либо косяков? Можно ли считать memoizedCalculation потокобезопасным? Может можно было решить проще? Я что-то упускаю?
A a1 = new A(cache, 42);
A a2 = new A(cache, 42);
B b = new B(cache, a1, a2);

в случае двух A c одинаковым value (как в примере 42) вычисление в А должно быть одно (уник. ключ 42) или два раза (уникальное на каждый объект A)?
источник