Log4j зависает в моем приложении, что я делаю не так?

StackOverflow https://stackoverflow.com/questions/634102

Вопрос

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

Ниже приведен фрагмент моих дампов потоков: все мои потоки в пуле-2 ЗАБЛОКИРОВАНЫ «пулом-2-потоком-78».Кажется, он заблокирован при попытке записи на консоль, что мне кажется крайне странным.Может ли кто-нибудь пролить свет на ситуацию для меня?

РЕДАКТИРОВАТЬ:Подробная информация о платформе Java версия "1.6.0_07" Java (TM) SE среда выполнения (сборка 1.6.0_07-b06) Java Hotspot (TM) VM VM (Build 10.0-B23, смешанный режим, обмен)

Сервер Ubuntu Linux с двумя четырехъядерными процессорами.

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

соответствующий раздел из моего log4j

log4j.rootlogger = debug, stdout log4j.logger.com.blah = info, log4j.appender.stdout = org.apache.log4j.consoleapdend

Извлечение дампа потока

"Pool-2-Thread-79" ID = 149 заблокирован на org.apache.log4j.spi.rootlogger@6c3ba437, принадлежащем "Pool-2-thread-78" ID = 148 на org.apache.log4j.category.callappenders ( Category.java:201) по адресу org.apache.log4j.category.forcedlog (Category.java:388) на org.apache.log4j.category.error (Category.java:302) на com.blah.messageprocesstas .java: 103) на java.util.concurrent.executors $ runnableadapter.call (experators.java:441) по адресу java.util.concurrent.futuretask $ sync.innerrun (futuretask/java: 268) на java.util.concurrent. FutureTask.Run (FutureTask/Java: 54) на java.util.concurrent.threadpoolexecutor $ abruntask (threadpoolexecutor.java:885) at java.util.concurrent.treadpoolexecutor $ koryer.run (threadpoolexecutor .lang.thread.run (Thread.java:619)

«Pool-2-Thread-78» ID = 148 Runnable на java.io.fileOutputStream.WriteBytes (нативном методе) по адресу java.io.fileOutputStream.Write (fileOutputStream.java:260) на java.io.bufferedoutptream.write (bufferenoutoutputstream) на java.io.io.bufferedoutpream.write (bufferenoutoutputstream). .java: 105) - заблокирован <0x6f314ba4> (java.io.bufferedoutputstream) на java.io.printstream.write (printstream.java:430) - Заблокирован <0xd5d3504> (java.io.printstream) на Org.apache .log4j.consoleappender $ systemoutstream.write (consoleappender.java:173) на sun.nio.cs.streamencoder.writebytes (streamencoder.java:202) на sun.nio.cs.streamencoder.implflushbuffer (Streamencoder.java:272) sun.nio.cs.streamencoder.implflush (streamencoder.java:276) на sun.nio.cs.streamencoder.flush (Streamencoder.java:122) - Заблокировано <0x6243a076> (java.io.outputstreamwriter) у Java.io.io.io.io.io.io.io.io.io .OutputStreamWriter.flush (uptureStreamWriter.java:212) на org.apache.log4j.helpers.quietwriter.flush (witewriter.java:57) на org.apache.log4j.writerappender.subappend (writerappender.java:315) на org. apache.log4j.writerappender.append (writerappender.java:159) на org.apache.log4j.appenderskeleton.doappend (appenderskeleton.java:230) - Заблокирован <0x45dbd560> (a org.apache.log4j.consoleapender) org.apach .log4j.helpers.appenderAttachableImpl.appendLooponAppenders (AppenderAttachableImpl.java:65) на org.apache.log4j.category.callappenders (категория. org.apache.log4j.category.forcedlog (category.java:388) на org.apache.log4j.category.error (Category.java:302) на com.blah.messageprocesstas .util.concurrent.executors $ runnableadapter.call (experators.java:441) по адресу java.util.concurrent.futuretask $ sync.innerrun (FuturoTas : 54) at java.util.concurrent.threadpoolexecutor $ abrontask (threadpoolexecutor.java:885) на java.util.concurrent.threadpoolexecutor $ keormer.run (threatolexecutor.java:907) по адресу java.lang. Thread.java:619)

Это было полезно?

Решение

Вы можете использовать AsyncAppender, чтобы лучше отсоединить регистратор от приложений.

В Windows, если вы щелкните в окне консоли, это приостановит консоль, например.буфер stdout заполнится, и по мере того, как консольное приложение записывает последовательно, ваше приложение будет зависать, пока вы не отпустите консоль (нажмите Enter или около того).

Рассмотрите возможность использования AsyncAppender с log4j - в большинстве случаев это хорошая идея - единственная проблема заключается в том, что буфер AsynAppender не очищается полностью при выходе.

Другие советы

во-первых, я считаю, что log4j записывает файлы и консоль последовательно, иначе все ваши журналы будут повреждены.поэтому, пока один поток пишет, другой поток, который хочет писать, должен дождаться завершения другого потока.Кроме того, стандартный вывод может блокироваться, если все, что подключено к нему на другом конце, не истощает его.

в unix есть специальный файловый дескриптор, называемый stdout.при запуске приложений в консоли к консоли будет прикреплен стандартный вывод.вы также можете перенаправить стандартный вывод в другие файлы.бывший:java Бла > /dev/null.скорее всего, у вас есть стандартный вывод, указывающий на файл, который заполняется.например, канал — это файл, и если программа на другом конце не очищает канал, то программа, записывающая в канал, в конечном итоге заблокируется.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top