|
|
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
хотя это всё равно не позволит несколько читателей сразу... надо ещё подумать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.02.2017, 23:19 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
авторчто конкретно не так с конструктором? какие проблемы могут быть? мне кажется synchronized даёт все необходимые гарантии А где у вас hb между вызовом конструктора и вызовом методов pop/push...? В предыдущей теме столько обсуждали... Еще добавлю про Ваш код - обычно размер стека динамический, т.е. заранее не задается, в таком случае нафига мьютекс на запись? Ок, мы оставляем синхронайзд только для notify, но тут проблема - у нас то, где хранятся элементы совсем не конкаррент. Поэтому я бы сделал так: Вот это lock-free стэк: Код: 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. А вот так - тот BlockingStack, который Вам и нужен: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. questioner, Вам вот задание (ну Вы же сами просили) - написать метод size() для ConcurrentStack. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.02.2017, 23:30 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
Чего-то я тупанул, всё оба действия ведь модифицируют коллекцию, соответственно 2 потока одновременно не могут производить операции Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.02.2017, 23:38 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
вот такой вариант наверное будет работать, но медленно: Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.02.2017, 23:53 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
no56892 Еще добавлю про Ваш код - обычно размер стека динамический, т.е. заранее не задается, в таком случае нафига мьютекс на запись? Ок, мы оставляем синхронайзд только для notify, но тут проблема - у нас то, где хранятся элементы совсем не конкаррент. Не понял причинно-следственной связи. мы оставляем synchronized дабы исключить параллельное изменение коллекции потоками. no56892 Поэтому я бы сделал так: Вот это lock-free стэк: Код: 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. Вроде да, должно работать, но по-моему это то же самое, что я написал(спору нет, после Вас). А вот так - тот BlockingStack, который Вам и нужен: no56892 Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. я не понял идею. явно где-то не хватает semaphore.take() авторquestioner, Вам вот задание (ну Вы же сами просили) - написать метод size() для ConcurrentStack.[/quote] Судя по всему надо, чтобы никто не работал в этот момент. Сейчас придумаю ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 00:12 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
ну и кстати концептуальный вопрос ещё: конструкция вида: Код: java 1. 2. 3. 4. //2 Как я понимаю мы пытаемся симулировать ситуацию, что между //1 и //2 никаких действий не произошло. Но ведь за это время мог элемент добавиться и удалиться, а в итоге состояние то же с точки зрения нашей проверки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 00:41 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
questioner Но ведь за это время мог элемент добавиться и удалиться, а в итоге состояние то же с точки зрения нашей проверки. Гугли по ключевым словам проблема ABA ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 00:52 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
забыл никquestionerНо ведь за это время мог элемент добавиться и удалиться, а в итоге состояние то же с точки зрения нашей проверки. Гугли по ключевым словам проблема ABA В языках с управляемой памятью не критично, в данном случае все будет ок ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 00:57 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
авторНе понял причинно-следственной связи. мы оставляем synchronized дабы исключить параллельное изменение коллекции потоками. Написал немного не то, что хотел сказать авторВроде да, должно работать, но по-моему это то же самое, что я написал(спору нет, после Вас). Это совершенно разные вещи, Вы написали опять с локами, только в отличие от первого варианта с synchronized (который, кстати хотя бы работает), здесь у Вас формально CAS, но только формально, в Вашей реализации это те же локи. Написать над методом non blocking и вставиеь busy-wait - это мощно. авторя не понял идею. явно где-то не хватает semaphore.take() В Java SE API)) авторСудя по всему надо, чтобы никто не работал в этот момент. Сейчас придумаю Опять локи? По коду: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Если срабатывает условие (A) весь стэк навесгда в busy-wait...Ну и немного не понятное у Вас Апи - через offer мы не можем больше max положить, а через put - можем? Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. (A) - допустим у нас есть 1+ элементов в стэке уже и один поток уже получил лок и кладет его туда, тоесть получается вернет null? Хотя там есть элементы... Нафига AtomicBoolean volatile? Конструктор не safe с точки зрения JLS, хотя на практике спасет хотя бы одно final поле, но я бы так не писал. Ну и все эти Код: java 1. 2. 3. ничем не отличаются от lock.lock()/unlock() кроме того, что забываете unlock делать. авторКак я понимаю мы пытаемся симулировать ситуацию, что между //1 и //2 никаких действий не произошло. Если произошло - повторяем цикл заново. "!" забыли. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 01:12 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
no56892ничем не отличаются от lock.lock()/unlock() кроме того, что забываете unlock делать Ну и еще невозможностью "интерраптнуть" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 01:16 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
no56892no56892ничем не отличаются от lock.lock()/unlock() кроме того, что забываете unlock делать Ну и еще невозможностью "интерраптнуть" Нет, такое использование еще даже хуже - процессор жрет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 01:27 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
забыл никзабыл никпропущено... Гугли по ключевым словам проблема ABA В языках с управляемой памятью не критично, в данном случае все будет ок Да, я гуглил и видел фразу, что в языках с gc ее тяжело воспроизвести. Почему в данном случае все ок будет? Проверка ведь будет успешной. Смотрите, еще раз, сценарий такой: 1.Первый поток запомнил head 2. Далее другие потоки успели добавить и удалить элемент из стекла 3. Первый поток проверяет, что old == pointer и цикл кончится Почему мы здесь эту проблему не получим? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 09:40 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
questionerВдруг будет аргументированная критика. Ну, 1. Если назвать NonBlocking и потом все на synchronized методах это сильно. 2. Долго выяснять зачем ставить final на поля типа list и maxsize и не сделать этого. 3. Размер списка не уменьшается, мелочь конечно, но тогда почему бы не Код: java 1. 4. remove само по себе возвращает объект, повторный поиск лишний. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 09:58 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
questionerхотя это всё равно не позволит несколько читателей сразу... надо ещё подумать А нафиг стеку параллельные читатели-писатели? Овчинка выделки не стоит. P.S. И мне кажется что массива с указателем текущего положения будет вполне достаточно, ArrayList практически не нужен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 10:01 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
А главное, кого будум ждать, если тот, кто должен сделать следующий pull пытается сделать push, а стек переполнен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 10:10 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
Кстати про remove. Если один и тот же объект у тебя лежит два раза в list. Что будет по remove(t)? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 10:17 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
Сергей АрсеньевquestionerВдруг будет аргументированная критика. Ну, 1. Если назвать NonBlocking и потом все на synchronized методах это сильно. это уже обсудили, Вы не дочитали Сергей Арсеньев 2. Долго выяснять зачем ставить final на поля типа list и maxsize и не сделать этого. Похоже и там и там правда нужен. Была мысль, что раз меняем в sync секции, то и не надо, но начальная инициализация может ускользнуть Сергей Арсеньев 3. Размер списка не уменьшается, мелочь конечно, но тогда почему бы не Код: java 1. такая задача не ставилась Сергей Арсеньев 4. remove само по себе возвращает объект, повторный поиск лишний. согласен, но не этот аспект был интересен, поэтому не заморчивался Сергей АрсеньевЕсли один и тот же объект у тебя лежит два раза в list. Что будет по remove(t)? удалится первый, а нужен последний, согласен, но, эти кейсы не столь интересны для меня в этой задаче ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 10:31 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
questionerудалится первый, а нужен последний, согласен, но, эти кейсы не столь интересны для меня в этой задаче Для начала надо понять задачу, а потом ее параллелить. Это основной принцип. Если Вы не уделяете внимания тому, что делаете что вставляем, что удаляем, то браться за параллельное выполнение этих действий - только плодить множество ошибок. Да и сам выбор задачи не удачен. Профита от неблокирования тут никакого. Тут еще есть смысл в подборе правильной блокировки, поиске зацикливаний и т.п., но не более того. В смысле неблокирующих операций лучше посмотреть на вариант перевода средств между счетами типа списать у Иванова 10 записать Петрову (желательно, чтоб денег хватало, не было бы взаимоблокировок и чтоб Сидоров не обогатился на этом). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 11:06 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
забыл никзабыл никпропущено... Гугли по ключевым словам проблема ABA В языках с управляемой памятью не критично, в данном случае все будет ок а тут пишут, что вполне может http://www.ibm.com/developerworks/library/j-jtp11234/ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 11:49 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
no56892, no56892Это совершенно разные вещи, Вы написали опять с локами, только в отличие от первого варианта с synchronized (который, кстати хотя бы работает), здесь у Вас формально CAS, но только формально, в Вашей реализации это те же локи. Написать над методом non blocking и вставиеь busy-wait - это мощно. а вот я правда не очень понимаю чем мой цикл от Вашего отличается. Насчёт дырок в логике, да, всё верно. скопирую рядом: Код: java 1. 2. 3. 4. 5. 6. 7. 8. Код: java 1. 2. 3. 4. 5. 6. по-моему у Вас наоборот плохо в цикле, что каждый раз новый объект создаётся. у меня вот один раз я захватил всё добро и только тогда делаю объек, хотя это время лока удлиняет. наверное один раз заранее лучше сделать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 12:00 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
questionerзабыл никпропущено... В языках с управляемой памятью не критично, в данном случае все будет ок а тут пишут, что вполне может http://www.ibm.com/developerworks/library/j-jtp11234/ Опять видимо в ваших фантазиях. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 12:01 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
забыл никquestionerпропущено... а тут пишут, что вполне может http://www.ibm.com/developerworks/library/j-jtp11234/ Опять видимо в ваших фантазиях. аргументированно ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 12:03 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
questionerno56892, no56892Это совершенно разные вещи, Вы написали опять с локами, только в отличие от первого варианта с synchronized (который, кстати хотя бы работает), здесь у Вас формально CAS, но только формально, в Вашей реализации это те же локи. Написать над методом non blocking и вставиеь busy-wait - это мощно. а вот я правда не очень понимаю чем мой цикл от Вашего отличается. Насчёт дырок в логике, да, всё верно. скопирую рядом: Код: java 1. 2. 3. 4. 5. 6. 7. 8. Код: java 1. 2. 3. 4. 5. 6. по-моему у Вас наоборот плохо в цикле, что каждый раз новый объект создаётся. у меня вот один раз я захватил всё добро и только тогда делаю объек, хотя это время лока удлиняет. наверное один раз заранее лучше сделать Мысли спутались пока писал)) у меня ж нет объекта никакого нового, мне его передают. а у Вас было бы оптимальнее создать объект до цикла, в начале цикла взять струю голову, у созданного объекта настроить ссылку на старый и вызвать CAS ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 12:13 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
questionerзабыл никпропущено... Опять видимо в ваших фантазиях. аргументированно Мусор на входе = мусор на выходе ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 12:16 |
|
||
|
codereview самописный потокобезопасный stack
|
|||
|---|---|---|---|
|
#18+
забыл никquestionerпропущено... аргументированно Мусор на входе = мусор на выходе я ссылку привел. вот цитата из нее: http://www.ibm.com/developerworks/library/j-jtp11234/ The ABA problem Because CAS basically asks "is the value of V still A" before changing V, it is possible for a CAS-based algorithm to be confused by the value changing from A to B and back to A between the time V was first read and the time the CAS on V is performed. In such a case, the CAS operation would succeed, but in some situations the result might not be what is desired. (Note that the counter and mutex examples from Listing 1 and Listing 2 are immune to this problem, but not all algorithms are.) This problem is called the ABA problem, and is generally dealt with by associating a tag, or version number, with each value to be CASed, and atomically updating both the value and the tag. The AtomicStampedReference class provides support for this approach. Статья про атомики ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2017, 12:18 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=39399924&tid=2123165]: |
0ms |
get settings: |
5ms |
get forum list: |
9ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
56ms |
get topic data: |
7ms |
get forum data: |
1ms |
get page messages: |
38ms |
get tp. blocked users: |
1ms |
| others: | 182ms |
| total: | 303ms |

| 0 / 0 |
