Этот простой код должен создать тупик, но это не так - PullRequest
0 голосов
/ 20 октября 2011

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

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

Я могу только думать, что код работает слишком быстро, но это кажется невероятным, чтобы все время .

Вот весь код: http://pastebin.com/HWJpuT38

Ответы [ 4 ]

8 голосов
/ 20 октября 2011

Проблема в этой строке:

mAccounts = new ArrayList<Account>(Collections.nCopies(slots, new Account()));

По сути, существует только один Account объект, но множество ссылок на него.Таким образом, вы когда-либо блокируете только один объект.

Если вы создаете много разных Account объектов, вы сможете увидеть тупик довольно быстро.

0 голосов
/ 20 октября 2011
mAccounts = new ArrayList<Account>(Collections.nCopies(slots, new Account()));

http://download.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html#nCopies%28int,%20java.lang.Object%29

В итоге вы получите список из 2 ссылок на один и тот же объект.

Этот объект может быть заблокирован только одним потоком за раз.У вас никогда не может быть тупика.

Я предполагаю, что вы хотели инициализировать mAccounts двумя различными экземплярами класса Account.

0 голосов
/ 20 октября 2011

Я думаю, вам нужно добавить некий сон в ваш цикл в AccountTransferRunnable, иначе планировщик будет запускать поток до конца, прежде чем запускать другой.

С помощью Sleep вы дадите Планировщику возможность переключиться на другой поток, если первый еще будет работать, что даст вашему коду шанс зайти в тупик.

0 голосов
/ 20 октября 2011

Единственное место, где у вас есть «оспариваемый» ресурс, это где вы синхронизируете на fromaccount, а затем на toaccount - все остальное зависит только от одной блокировки.

Если у вас был другой метод, который синхронизировался на toaccount, а затем на fromaccount, у вас может быть шанс вызвать взаимоблокировку, но, поскольку код в настоящее время таков, он должен быть совершенно корректно.

...