|
|
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#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. Иногда программа правильно выполняется, а иногда вываливается ошибка windows: автор00005 Смещение исключения: 000000000009970a Версия ОС: 6.1.7601.2.1.0.256.1 Код языка: 1049 Дополнительные сведения 1: 4c0d Дополнительные сведения 2: 4c0d4d78887f76d971d5d00f1f20a433 Дополнительные сведения 3: 4c0d Дополнительные сведения 4: 4c0d4d78887f76d971d5d00f1f20a433 вываливается 1 раз на 10 запусков в среднем ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2013, 02:18:39 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
redwhite90Иногда программа правильно выполняется, а иногда вываливается ошибка windows:автор00005 Смещение исключения: 000000000009970a Версия ОС: 6.1.7601.2.1.0.256.1 Код языка: 1049 Дополнительные сведения 1: 4c0d Дополнительные сведения 2: 4c0d4d78887f76d971d5d00f1f20a433 Дополнительные сведения 3: 4c0d Дополнительные сведения 4: 4c0d4d78887f76d971d5d00f1f20a433вываливается 1 раз на 10 запусков в среднем1. При падениях JVM должен создаваться дамп стека и записываться, вместе с дополнительной информацией, в лог-файл. 2. Логировать не пробовали? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2013, 09:28:26 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
Привет. Рассмотрите проблему в service.shutdown(); Ведь он може быть вызван пока не отработано service.submit System.out.println(service.submit(new CallableClass(x, 0, 5)).get()); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2013, 12:09:43 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
redwhite90... Integer x[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; ... эта переменная должна быть finall - вы же её в другой поток передаете. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2013, 21:22:42 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
_quark_эта переменная должна быть finall - вы же её в другой поток передаете. LOL. Ничего что она локальная? И сама переменная не модифицируется. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2013, 22:15:54 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
Ну, во-первых, хотя программа и многопоточная, выполняться она будет строго последовательно. Во-вторых, ошибки вроде быть не должно, возможно, проблема в конкретной версии jvm, уточните, что используете ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 10:36:50 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
ivanraНу, во-первых, хотя программа и многопоточная, выполняться она будет строго последовательно. Во-вторых, ошибки вроде быть не должно, возможно, проблема в конкретной версии jvm, уточните, что используете Почему это? Насколько я понимаю тут будет 3 потока: 1 основной и по одному для каждого задания Blazkowicz_quark_эта переменная должна быть finall - вы же её в другой поток передаете. LOL. Ничего что она локальная? И сама переменная не модифицируется. В том то и дело, что она локальная. Модель памяти Java не гарантирует, что x[] будет инициализирована раньше, чем начнут выполнятся новые потоки. finall это гарантирует. Почитайте Java Concurrency in Practice - узнаете много нового. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 14:58:53 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
_quark_В том то и дело, что она локальная. Вы наверное про поле CallableClass ? _quark_Модель памяти Java не гарантирует, что x[] будет инициализирована раньше, чем начнут выполнятся новые потоки. Мгу. Зато она гарантирует что выполнение конструктора будет закончено до вызова метода submit(). _quark_finall это гарантирует. Почитайте Java Concurrency in Practice - узнаете много нового. Здесь гонок нет. Если даёте ссылку то давайте на конкретную главу, хотя бы. А так пальцем в небо. Читал. Узнал много нового. Как это применяется к указанному коду? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 15:07:37 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
_quark_В том то и дело, что она локальная. Модель памяти Java не гарантирует, что x[] будет инициализирована раньше, чем начнут выполнятся новые потоки. finall это гарантирует. Почитайте Java Concurrency in Practice - узнаете много нового. Вот здесь описано например. http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#finalRight Значения поля, действительно, можно не увидеть в другом потоке, если поле не final и конструктор предоставляет ссылку на экземпляр другому потоку до окончания выполнения конструктора . Т.е. другой поток должен получит ссылку на CallableClass, до окончания выполнения CallableClass<init>. Чего в данном примере не наблюдается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 15:17:45 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
BlazkowiczВы наверное про поле CallableClass ? Нет я имел ввиду именно локальную переменную x метода main. А именно то, что она может передаться новым потокам непроинициализированной. Blazkowicz_quark_finall это гарантирует. Почитайте Java Concurrency in Practice - узнаете много нового. Здесь гонок нет. Если даёте ссылку то давайте на конкретную главу, хотя бы. А так пальцем в небо. Читал. Узнал много нового. Как это применяется к указанному коду? Глава 3.5. Safe Publication 3.5.1. Improper Publication: When Good Objects Go Bad You cannot rely on the integrity of partially constructed objects. An observing thread could see the object in an inconsistent state, and then later see its state suddenly change, even though it has not been modified since publication. In fact, if the Holder in Listing 3.15 is published using the unsafe publication idiom in Listing 3.14, and a thread other than the publishing thread were to call assertSanity, it could throw AssertionError![15] [15] The problem here is not the Holder class itself, but that the Holder is not properly published. However, Holder can be made immune to improper publication by declaring the n field to be final, which would make Holder immutable; see Section 3.5.2. Listing 3.15. Class at Risk of Failure if Not Properly Published. Код: java 1. 2. 3. 4. 5. 6. 7. 8. Because synchronization was not used to make the Holder visible to other threads, we say the Holder was not properly published. Two things can go wrong with improperly published objects. Other threads could see a stale value for the holder field, and thus see a null reference or other older value even though a value has been placed in holder. But far worse, other threads could see an up to date value for the holder reference, but stale values for the state of the Holder. [16] To make things even less predictable, a thread may see a stale value the first time it reads a field and then a more up to date value the next time, which is why assertSanity can throw AssertionError. [16] While it may seem that field values set in a constructor are the first values written to those fields and therefore that there are no "older" values to see as stale values, the Object constructor first writes the default values to all fields before subclass constructors run. It is therefore possible to see the default value for a field as a stale value. At the risk of repeating ourselves, some very strange things can happen when data is shared across threads without sufficient synchronization. ... 3.5.2. Immutable Objects and Initialization Safety ... To publish an object safely, both the reference to the object and the object's state must be made visible to other threads at the same time. A properly constructed object can be safely published by: Initializing an object reference from a static initializer; Storing a reference to it into a volatile field or AtomicReference; Storing a reference to it into a final field of a properly constructed object; or Storing a reference to it into a field that is properly guarded by a lock. В данном случае локальная переменная x метода main как раз публикуется (передается конструкторам CallableClass) не безопасно. Поэтому другие потоки могут увидеть её в непроинициализированном состоянии. final обеспечивает безопасную публикацию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 15:41:42 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
в данном случае отвественность за безопасную публикацию берет на себя ExecutorService. ТС, а ты случайно не на шаред хостинге это все гоняешь? Помню у меня были дикие траблы когда я разворачивал приложение на VPS с системой виртуализации OpenVZ, как раз в случае многопоточных программ. Пока писал, понял что сморозил глупость - у тебя же венда:) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 15:51:34 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
забыл никв данном случае отвественность за безопасную публикацию берет на себя ExecutorService. ExecutorService берет на себя ответственность за безопасную публикацию только экземпляров CallableClass. Локальная переменная x метода main опубликована небезопасно - поэтому значением поля x экземпляров CallableClass потоки могут увидеть самые странные значения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 16:03:59 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
_quark_забыл никв данном случае отвественность за безопасную публикацию берет на себя ExecutorService. ExecutorService берет на себя ответственность за безопасную публикацию только экземпляров CallableClass. Локальная переменная x метода main опубликована небезопасно - поэтому значением поля x экземпляров CallableClass потоки могут увидеть самые странные значения. Угу, сразу после конструирования, которое идет после инициализации массива, и оба действия происходят в одном потоке, сохраняя при этом total order of execution. Этакий piggybacking. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 16:19:50 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
забыл никУгу, сразу после конструирования, которое идет после инициализации массива, и оба действия происходят в одном потоке, сохраняя при этом total order of execution. Этакий piggybacking. Именно. Модель памяти java при многопоточности так и работает. Потоки задач уже могут выполнять CallableClass.call(), а локальная переменная x метода main может быть все-еще непроинициализированна. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 16:48:42 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
_quark_Глава 3.5. Safe Publication 3.5.2. Immutable Objects and Initialization Safety Речь исключительно о полях и объектах. Ни слова о локальных переменных и массивах. И это тоже самое на что я привел ссылку выше. _quark_В данном случае локальная переменная x метода main как раз публикуется Ну, начинается - "локальная переменная публикуется". Публикуются объекты, а не переменные. Публикуется массив. По вашему этот массив может быть не до конца инициализирован? Или в чем проявляется unsafe publication? _quark_(передается конструкторам CallableClass) не безопасно. Поэтому другие потоки могут увидеть её в непроинициализированном состоянии. final обеспечивает безопасную публикацию. Дальнейшие рассуждение смысла не имеют, так как вы переменную от объекта не отличаете. Попробуйте сформулировать кто именно и как именно здесь публикуется не безопасно в терминах экземпляров. Тогда обсудим. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 16:58:12 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
_quark_В данном случае локальная переменная x метода main как раз публикуется (передается конструкторам CallableClass) не безопасно. Поэтому другие потоки могут увидеть её в непроинициализированном состоянии. final обеспечивает безопасную публикацию. И почему тогда вот этот Holder публикуется не безопасно? Код: java 1. 2. 3. 4. 5. 6. 7. 8. Ведь можно делать так и ... Код: java 1. 2. 3. и все состояние Holder-а безопасно опубликовано. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 17:09:13 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
BlazkowiczПо вашему этот массив может быть не до конца инициализирован? Да. BlazkowiczРечь исключительно о полях и объектах. Массив x это объект (аналогично экземпляру класса Holder из примера). Потоки заданий могут увидеть его в непроинициализированном состоянии. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 17:11:11 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
_quark_Потоки задач уже могут выполнять CallableClass.call(), а локальная переменная x метода main может быть все-еще непроинициализированна. "непроинициализировання" переменная это ссылка на null. Т.е по вашему локальная переменная на стеке, вместо ссылки на массив будет почему-то содержать ссылку на null? И этот null будет использован при вызове конструктора CallableClass в том же методе? Звучит как бред? Или речь таки об инициализации массива и его публикации? Т.е. массив может быть не заполнен? Но как это связано с финальностью локальной переменной? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 17:19:58 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
schwa_quark_В данном случае локальная переменная x метода main как раз публикуется (передается конструкторам CallableClass) не безопасно. Поэтому другие потоки могут увидеть её в непроинициализированном состоянии. final обеспечивает безопасную публикацию. И почему тогда вот этот Holder публикуется не безопасно? Код: java 1. 2. 3. 4. 5. 6. 7. 8. Ведь можно делать так и ... Код: java 1. 2. 3. и все состояние Holder-а безопасно опубликовано. В примере Holder вообще не публикуется. Публикация происходит тогда, когда экземпляр класса Holder будет передается другому потоку. Если вы опубликуете объект класса Holder безопасно - то все будет ОК. Если нет, то другой поток может увидеть этот объект в состоянии, когда выполнение конструктора этого объекта в основном потоке еще не закончилось. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 17:21:04 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
_quark_BlazkowiczПо вашему этот массив может быть не до конца инициализирован? Да. Но final таки влияет на состояние самой ссылки. На процесс инициализации элементова массива он никак не влияет. _quark_Массив x это объект (аналогично экземпляру класса Holder из примера). Потоки заданий могут увидеть его в непроинициализированном состоянии. Т.е. некоторые элементы будут null? Вы это хотите сказать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 17:22:11 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
schwaИ почему тогда вот этот Holder публикуется не безопасно? Там говорится что проблема не в самом holder, а в том что если он публикуется не безопасно, то значение n может быть не проинициализированым. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 17:27:12 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
Blazkowicz_quark_Потоки задач уже могут выполнять CallableClass.call(), а локальная переменная x метода main может быть все-еще непроинициализированна. "непроинициализировання" переменная это ссылка на null. Т.е по вашему локальная переменная на стеке, вместо ссылки на массив будет почему-то содержать ссылку на null? И этот null будет использован при вызове конструктора CallableClass в том же методе? Звучит как бред? Еще веселее. Т.к. локальные переменные не инициализируются значениями по умолчанию, то локальная переменная x может содержать ссылку на "недостроенный" массив (т.е. этот самый массив может как раз инициализироваться основным потоком, когда поток задачи к нему обращается). BlazkowiczИли речь таки об инициализации массива и его публикации? Т.е. массив может быть не заполнен? Но как это связано с финальностью локальной переменной? С final фича в том, что если локальную переменную x объявить finall , то она сначала проинициализируется, а уже только потом эта переменная будет использоваться в new CallableClass(x, 0, 5). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 17:31:40 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
_quark_, Вы не правы в данном случае. Рассмотрим по порядку - 1) идет инициализация массива и присваивание переменной ссылки на него 2) идет конструирование Callable в ТОМ же потоке, модель памяти java гарантирует что компилятор никак не должен ломать total execution of order внутри исполнения ОДНОГО потока, таким образом Callable будет гарантировано сконструирован правильно. 3) Далее мы ложим Callable в экзекьютор и экзекьютор сам уже заботится о публикации ссылки на Callable Таким образом код абсолютно корректен. А вот если бы массив был параметром к методу, или полем класса - тогда да, возможны варианты, потому что непонятно в каком потоке он был создан. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 17:43:25 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
_quark_schwaпропущено... И почему тогда вот этот Holder публикуется не безопасно? Код: java 1. 2. 3. 4. 5. 6. 7. 8. Ведь можно делать так и ... Код: java 1. 2. 3. и все состояние Holder-а безопасно опубликовано. В примере Holder вообще не публикуется. Публикация происходит тогда, когда экземпляр класса Holder будет передается другому потоку. Если вы опубликуете объект класса Holder безопасно - то все будет ОК. Если нет, то другой поток может увидеть этот объект в состоянии, когда выполнение конструктора этого объекта в основном потоке еще не закончилось. И каким тут образом тогда в примере из стартового сообщения получается небезопасная публикация содержимого массива, если состояние коллабл, публикуется безопасно экзекутором? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 17:47:04 |
|
||
|
Непостоянная ошибка при работе многопоточной программы
|
|||
|---|---|---|---|
|
#18+
BlazkowiczНо final таки влияет на состояние самой ссылки. На процесс инициализации элементова массива он никак не влияет. Как раз таки влияет, но именно при инициализации. Если после один из элементов массива будет изменен в одном из потоков, то другие потоки могут продолжить видеть старое содержимое массива. Опять же в Java Concurrency in Practice это описывается в Chapter 16. The Java Memory Model. Есть так называемые правила happens before 16.2.2. Safe Publication The safe publication idioms described in Chapter 3 ensure that the published object is visible to other threads because they ensure the publication happens before the consuming thread loads a reference to the published object. если переменную локальную переменную x объявить finall, то тем самым мы её безопасно опубликуем для потоком задач и таким образом потоки гарантированно будут видеть её в проинициализированном состоянии. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2013, 17:48:15 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=38109511&tid=2130191]: |
0ms |
get settings: |
12ms |
get forum list: |
18ms |
check forum access: |
8ms |
check topic access: |
8ms |
track hit: |
375ms |
get topic data: |
17ms |
get forum data: |
4ms |
get page messages: |
99ms |
get tp. blocked users: |
3ms |
| others: | 282ms |
| total: | 826ms |

| 0 / 0 |
