Еще один способ:
char[] chars = {'a', ' ', 's', 't', 'r', 'i', 'n', 'g'};
string s = string.Join("", chars);
//we get "a string"
// or for fun:
string s = string.Join("_", chars);
//we get "a_ _s_t_r_i_n_g"
вы можете использовать jconsole или jstack как в каталоге bin вашего JDK. В частности, jconsole позволяет вам подключаться к вашему процессу и отслеживать потоки, включая то, какие ресурсы они заблокировали, и может помочь вам определить состояние тупика.
Вы также можете просмотреть это в отладчике eclipse. В представлении отладки используйте маленькое треугольное меню на панели инструментов представления, чтобы включить «Java-> Показать мониторы».
Если вы подозреваете тупиковую ситуацию, приостановите приложение (выберите приложение в представлении отладки и нажмите кнопку кнопку паузы на панели инструментов просмотра отладки), и в случае тупиковой ситуации блокирующие потоки станут красными. Если развернуть эти потоки, можно увидеть конфликт блокировок.
JDK имеет некоторую встроенную поддержку - под unix, kill -3 процесс, под windows, ctrl-break. Это отобразит полный дамп потока с последующими обнаруженными взаимоблокировками. Кроме того, в потоке dusmp вы можете увидеть, какие потоки и какие блокировки владеют, и сравнить их друг с другом.
Если вы владеете кодом, вы можете создать / найти реализацию блокировки, которая собирает статистику конкуренции. Если нет, попробуйте инструменты, предложенные в других сообщениях.