|
|
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
no56892Вот это lock-free стэк: Это ,так называемый, lock-free стэк. Ибо 1. compareAndSet - это и есть блокировка, просто она wait free. Вслед за этим все заворачивается в цикл, который как раз и реализует это ожидание. Поэтому алгоритм не "без блокировок" и не "без ожиданий". 2. Это даже не стек. Ибо в силу отсутствия сериализации вполне допускается ситуация, когда поток будет пытаться вставить элемент, но у него это достаточно долго не будет получаться, при том, что другие потоки будут вставлять и вынимать объекты из "стека". 3. Гонять в цикле генератор новый Entry, при том, что достаточно менять одну ссылку это перебор. 3а. Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. При пустом стеке может забрать новый элемент. Что, правда, может и не плохо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 12:27 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
questionerзабыл никпропущено... Мусор на входе = мусор на выходе я ссылку привел. вот цитата из нее: Я видел, не поленился даже поискать, и только после этого и ответил. Как это расходится с моими словами? Где там хоть слово про стэк и managed память? Все зависит от алгоритма. В unmanaged языках существует дополнительная проблема, когда поток держит ссылку, которая уже удалена другим потоком и потом может внезапно обновиться ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 12:28 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
questionerСтатья про атомики В данном случае, никогда не будет удачной попытки вставить один и тот же элемент (Entry) в силу этого и не может повторно оказаться та же величина для сравнения. Просто реализовывать свою блокировку на атомиках через true false, а безсмысленно, б уж лучше id потока использовать на предмет кто последний захватил, типа Код: java 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 12:39 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
Сергей Арсеньев, Точнее может, но это не важно, в этом случае нам не важно, что в промежутке вершина стека менялась, главное, что на этот момент она там же и ничего ниже ее не вынималось. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 12:43 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
Сергей АрсеньевВ данном случае, никогда не будет удачной попытки вставить один и тот же элемент почему? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 13:13 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
Сергей Арсеньев, тогда операция ведь формально не атомарно. между взятием старого значения и проверкой могло произойти вставка ещё 100 элементов сверху и 101-ым вставили опять старый элемент ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 13:16 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
А чем не нравится https://docs.oracle.com/javase/7/docs/api/java/util/Stack.html ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 13:19 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
questionerСергей Арсеньев, тогда операция ведь формально не атомарно. между взятием старого значения и проверкой могло произойти вставка ещё 100 элементов сверху и 101-ым вставили опять старый элемент И что это меняет? Вам вот правильно говорят, сначала определитесь как алгоритм в вашем понимании должен ПРАВИЛЬНО работать. Есть fair-locking, когда важно в каком порядке будут вставляться элементы(или изменяться shared объекты), а когда необходима просто консистентность. В вашем случае нужна просто консистентность, так что неважно что еще 100 потоков там что-то надобавлялт, структура ведь остается корректной ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 13:22 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
забыл ника когда необходима просто консистентность. Читать как "а есть non-fair когда необходима просто консистентность." ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 13:23 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
questionerмежду взятием старого значения и проверкой могло произойти вставка ещё 100 элементов сверху и 101-ым вставили опять старый элемент Поэтому вставляют и сравнивают не сам элемент, а Entry. Которое по сути является ссылкой на этот элемент и на предыдущее Entry. Entry для каждой вставки новое. Да алгоритм проигнорирует ситуацию, когда прошло 100 (n) вставок и 100 (n) забираний элементов между получением старой вершины и попыткой вставки новой. Но в данном случае это не важно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 13:25 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
Сергей Арсеньевquestionerмежду взятием старого значения и проверкой могло произойти вставка ещё 100 элементов сверху и 101-ым вставили опять старый элемент Поэтому вставляют и сравнивают не сам элемент, а Entry. Которое по сути является ссылкой на этот элемент и на предыдущее Entry. Entry для каждой вставки новое. Да алгоритм проигнорирует ситуацию, когда прошло 100 (n) вставок и 100 (n) забираний элементов между получением старой вершины и попыткой вставки новой. Но в данном случае это не важно. это меткое замечание ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 13:29 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
забыл ник структура ведь остается корректной Для понятия "стек" важен порядок вставки и забирания элементов (LIFO). Если он не важен, то это уже не стек. Более того, в силу того, что в отличии от очереди, тут не получится даже развести читателя и писателя (они конкурируют за право изменить один и тот же указатель). А действий, которые надо совершить (проверка заполненности, изменение указателя вершины, возможно обнуление старой ссылки, возврат значения), раз-два и обчелся. Смысла нет обойтись без блокировки - можно не не такой уж и выигрыш по скорости, плюс расходы на генерацию (и последующую работу GC) новых Entry (против массива и индекса вершины). Не та задача, где стоит ломать копья. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 13:36 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 13:42 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
Сергей Арсеньевзабыл ник структура ведь остается корректной Для понятия "стек" важен порядок вставки и забирания элементов (LIFO). Если он не важен, то это уже не стек. Более того, в силу того, что в отличии от очереди, тут не получится даже развести читателя и писателя (они конкурируют за право изменить один и тот же указатель). А действий, которые надо совершить (проверка заполненности, изменение указателя вершины, возможно обнуление старой ссылки, возврат значения), раз-два и обчелся. Смысла нет обойтись без блокировки - можно не не такой уж и выигрыш по скорости, плюс расходы на генерацию (и последующую работу GC) новых Entry (против массива и индекса вершины). Не та задача, где стоит ломать копья. Эмм, а кто спорит? Если вы про то что я криво вас процитировал, то это глюк сайта, я отвечал ТС. Видимо ему бороться с ветряными мельницами просто необходимо ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 13:50 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
забыл никquestionerСергей Арсеньев, тогда операция ведь формально не атомарно. между взятием старого значения и проверкой могло произойти вставка ещё 100 элементов сверху и 101-ым вставили опять старый элемент И что это меняет? Вам вот правильно говорят, сначала определитесь как алгоритм в вашем понимании должен ПРАВИЛЬНО работать. Есть fair-locking, когда важно в каком порядке будут вставляться элементы(или изменяться shared объекты), а когда необходима просто консистентность. В вашем случае нужна просто консистентность, так что неважно что еще 100 потоков там что-то надобавлялт, структура ведь остается корректной У меня диссонанс из-за того, что атомики не атомарны в моём понимании(наверное оно ошибочно) когда меня спрашивают на собесах что это такое и зачем они нужны я даю ответ, что они нужны для того, чтобы другой поток не вклинился между двумя операциями (increment and get допустим)? и я так понимал код, что между взятием старого значения и присвоением нового ничего не должно произойти, иначе новый цикл. а тут не совсем так получается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 13:57 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
забыл никЭмм, а кто спорит? Если вы про то что я криво вас процитировал, то это глюк сайта, я отвечал ТС. Видимо ему бороться с ветряными мельницами просто необходимо пфф, я изучаю инструмент, не более того ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 14:02 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
questionerУ меня диссонанс из-за того, что атомики не атомарны в моём понимании(наверное оно ошибочно) У Атомика есть куча операций, которые атомарны. Не более не менее. Между ними никакой атомарности никто не обещал. Для этого: ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 14:05 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
Сергей АрсеньевquestionerУ меня диссонанс из-за того, что атомики не атомарны в моём понимании(наверное оно ошибочно) У Атомика есть куча операций, которые атомарны. Не более не менее. Между ними никакой атомарности никто не обещал. Для этого: ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 14:14 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
questionerУ нас тут явно недопонимание По шагам. У атомика есть ряд атомарных операций. 1. pointer.get(); Атомарно 2. pointer.compareAndSet(currentTop, newTop); Атомарно Но никто не обещает Атомарность этих действий вместе. Поэтому между ними может вклинится кто-то другой. Сам по себе atomic не ведет учет своего состояния, поэтому нет операции ifNotChangedSet(). Делается через проверку старого значения. Но совпадение старого значения, не означает что состояние не менялось. В случае вставки в стек это все равно - при farness это не важно, главное, что вставляем в вершину. А это Atomic гарантирует, если это уже не тот экземпляр, то присвоения не будет (для этого у ней внутре миниблокировка, со всеми h-b бонусами, в отличии от weakCompareAndSet). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 14:28 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
автор1. compareAndSet - это и есть блокировка, просто она wait free. Вслед за этим все заворачивается в цикл, который как раз и реализует это ожидание. Поэтому алгоритм не "без блокировок" и не "без ожиданий". Строго говоря, это lock-free называется, см. http://www.1024cores.net/home/in-russian/lock--wait--obstruction--atomic-free-algorithms автор2. Это даже не стек. Ибо в силу отсутствия сериализации вполне допускается ситуация, когда поток будет пытаться вставить элемент, но у него это достаточно долго не будет получаться, при том, что другие потоки будут вставлять и вынимать объекты из "стека". Это starvation, есть такое, но из этого не следует, что это перестает быть стеком, следуя такой логике Collections.synchronized(deque) это тоже не стек, да и ConcurrentLinkedDeque тоже не стек. авторГонять в цикле генератор новый Entry, при том, что достаточно менять одну ссылку это перебор. + авторПри пустом стеке может забрать новый элемент. Что, правда, может и не плохо. +, надо добавить else return null; Да, кстати, а как наличие GC отменяет ABA? Вполне теоретически возможна ситуация, когда Entry собирается GC и new Entry возвращает объект по тому же адресу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 16:32 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
no56892Это starvation, есть такое, но из этого не следует, что это перестает быть стеком, следуя такой логике Collections.synchronized(deque) это тоже не стек, да и ConcurrentLinkedDeque тоже не стек. Ты не поверишь, но и java.util.Stack тоже не гарантирует порядка в этом вопросе. :) А так да. no56892Да, кстати, а как наличие GC отменяет ABA? Вполне теоретически возможна ситуация, когда Entry собирается GC и new Entry возвращает объект по тому же адресу. Ну если Entry не пересоздавать в цикле ожидания, то проблемы быть не должно.:) Ибо GC он не достанется, так как удерживается переменной в стеке потока, а то, что добавлено в "стек" удерживается "стеком". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 17:46 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
Только Entry надо создать до pointer.get(); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 17:50 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
Сергей Арсеньев, это я перемудрил ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 17:51 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
авторНу если Entry не пересоздавать в цикле ожидания, то проблемы быть не должно.:) Ибо GC он не достанется, так как удерживается переменной в стеке потока, а то, что добавлено в "стек" удерживается "стеком". Да, точно, я тупанул questioner, ну, что, придумал как написать size()?)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 17:55 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
Код: java 1. До этого момента Entry держится pointer, потом currentTop. Поэтому, эта ссылка не может собраться и выдаться еще кому-нибудь. Поэтому, повторно в стек попасть не может вплоть до конца цикла. А compareAndSet(currentTop, newTop) раньше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 18:00 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=39400339&tid=2123165]: |
0ms |
get settings: |
10ms |
get forum list: |
19ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
60ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
85ms |
get tp. blocked users: |
2ms |
| others: | 239ms |
| total: | 433ms |

| 0 / 0 |
