Log4j висит мое приложение, что я делаю не так? - PullRequest
13 голосов
/ 11 марта 2009

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

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

EDIT : Детали платформы Java-версия "1.6.0_07" Java (TM) SE Runtime Environment (сборка 1.6.0_07-b06) Клиентская виртуальная машина Java HotSpot (TM) (сборка 10.0-b23, смешанный режим, совместное использование)

Двухъядерный компьютер с Ubuntu Linux Server.

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

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

log4j.rootLogger = ОТЛАДКА, STDOUT log4j.logger.com.blah = INFO, LOG log4j.appender.STDOUT = org.apache.log4j.ConsoleAppender log4j.appender.LOG = org.apache.log4j.FileAppender

Извлечение дампа резьбы

"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.MessageProcessTask.run (MessageProcessTask.java:103) в java.util.concurrent.Executors $ RunnableAdapter.call (Executors.java:441) в java.util.concurrent.FutureTask $ Sync.innerRun (FutureTask / Java: 268) в java.util.concurrent.FutureTask.run (FutureTask / Java: 54) в java.util.concurrent.ThreadPoolExecutor $ Worker.runTask (ThreadPoolExecutor.java:885) в java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:907) в java.lang.Thread.run (Thread.java:619)

"Pool-2-thread-78" Id = 148, запускаемый при java.io.FileOutputStream.writeBytes (Native Метод) в java.io.FileOutputStream.write (FileOutputStream.java:260) в java.io.BufferedOutputStream.write (BufferedOutputStream.java:105) - заблокирован <0x6f314ba4> (a java.io.BufferedOutputStream) в java.io.PrintStream.write (PrintStream.java:430) - заблокирован <0xd5d3504> (a 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.OutputStreamWriter.flush (OutputStreamWriter.java:212) в org.apache.log4j.helpers.QuietWriter.flush (QuietWriter.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> (org.apache.log4j.ConsoleAppender) в org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders (AppenderAttachableImpl.java:65) в org.apache.log4j.Category.callAppenders (Category.java:203) - заблокирован <0x6c3ba437> (org.apache.log4j.spi.RootLogger) в org.apache.log4j.Category.forcedLog (Category.java:388) в org.apache.log4j.Category.error (Category.java:302) в com.blah.MessageProcessTask.run (MessageProcessTask.java:103) в java.util.concurrent.Executors $ RunnableAdapter.call (Executors.java:441) в java.util.concurrent.FutureTask $ Sync.innerRun (FutureTask / Java: 268) вjava.util.concurrent.FutureTask.run (FutureTask / Java: 54) в java.util.concurrent.ThreadPoolExecutor $ Worker.runTask (ThreadPoolExecutor.java:885) в java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:907) в java.lang.Thread.run (Thread.java:619)

Ответы [ 2 ]

12 голосов
/ 11 марта 2009

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

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

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

10 голосов
/ 11 марта 2009

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

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

...