2009-03-11 10 views
11

Najpierw trochę tła w aplikacji. Mam aplikację przetwarzającą wiele niezależnych zadań równolegle za pośrednictwem puli wątków. Pula wątków jest teraz zawieszona.Log4j zawiesza moją aplikację, co robię źle?

Poniżej znajduje się fragment z moich zrzutów wątku, wszystkie moje wątki w puli-2 są ZABLOKOWANE za pomocą "puli-2-wątku-78". Wygląda na to, że jestem zablokowany, próbując pisać na konsoli, co wydaje mi się niezwykle dziwne. Czy ktoś może rzucić mi choć trochę światła na sytuację?

EDIT: szczegóły Platforma wersja java "1.6.0_07" Java (TM) SE Runtime Environment (build 1.6.0_07-b06) Java HotSpot (TM) Client VM (build 10.0-B23, mieszane tryb, udostępnianie)

Ubuntu Linux serwer dual quad core machine.

Wygląda na to, że blokuje się podczas pisania do wydruku, rozważałem tylko usunięcie appendera konsoli, ale wolałbym wiedzieć, dlaczego blokuje i usuwa go w oparciu o tę wiedzę. W przeszłości usuń i zobacz czy działa wróciła do mnie :) ugryźć

odpowiedniej części z mojego log4j

log4j.rootLogger = Debug STDOUT log4j.logger.com.blah = INFO , Log log4j.appender.STDOUT = org.apache.log4j.ConsoleAppender log4j.appender.LOG = org.apache.log4j.FileAppender

ekstrakt wysypisko Temat

Identyfikator "pool-2-thread-79" Id = 149 BLOCKED na [email protected] właścicielem identyfikatora "pool-2-thread-78" Id = 148 at org.apache.log4j .Category.callAppenders (Category.java:201) w org.apache.log4j.Category.forcedLog (Category.java:388) w org.apache.log4j.Category.error (Category.java:302) w com.blah.MessageProcessTask.run (MessageProcessTask.java:103) w java.util.concurrent.Executors $ RunnableAdapter.call (Executors.java:441) w java.util.concurrent.FutureTask $ Sync. innerRun (FutureTask/java: 268) w java.util.concurrent.FutureTask.run (FutureTask/java: 54) na java.util.concurrent.ThreadPoolExecutor $ Worker.runTask (ThreadPoolExecutor.java:885) na java.util.concurrent.ThreadPoolExecutor $ Pracownika .run (ThreadPoolExecutor.java:907) w java.lang.Thread.run (Thread.java:619)

"pula-2-nitki 78" id = 148 uruchamialny w java.io.FileOutputStream .writeBytes (metoda Native ) pod adresem java.io.FileOutputStream.write (FileOutputStream.java:260) pod adresem java.io.BufferedOutputStream.write (BufferedOutputStream.java:105)- zamknięty < 0x6f314ba4> (a) co java.io.BufferedOutputStream java.io.PrintStream.write (PrintStream.java:430) - zamknięty < 0xd5d3504> (a java.io.PrintStream) w org.apache. log4j.ConsoleAppender $ SystemOutStream.write (ConsoleAppender.java:173) na sun.nio.cs.StreamEncoder.writeBytes (StreamEncoder.java:202) na sun.nio.cs.StreamEncoder.implFlushBuffer (StreamEncoder.java:272) na słońcu .nio.cs.StreamEncoder.implFlush (StreamEncoder.java:276) w sun.nio.cs.StreamEncoder.flush (StreamEncoder.java:122) - zamknięty < 0x6243a076> (a java.io.OutputStreamWriter) w java.io.OutputStreamWriter.flush (OutputStreamWriter.java:212) w org.apache.log4j.helpers.QuietWriter.flush (QuietWriter.java:57) w org.apache.log4j.WriterAppender.subAppend (WriterA ppender.java:315) w org.apache.log4j.WriterAppender.append (WriterAppender.java:159) w org.apache.log4j.AppenderSkeleton.doAppend (AppenderSkeleton.java:230) - zamknięty < 0x45dbd560> (a org.apache.log4j.ConsoleAppender) w org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders (AppenderAttachableImpl.java:65) w org.apache.log4j.Category.callAppenders (Category.java:203) - zablokowany < 0x6c3ba437> (a org.apache.log4j.spi.RootLogger) pod adresem org.apache.log4j.Category.forcedLog (Category.java:388) pod adresem org.apache.log4j.Category.error (Kategoria. java: 302) na com.blah.MessageProcessTask.run (MessageProcessTask.java:103) w java.util.concurrent.Executors $ RunnableAdapter.call (Executors.java:441) w java.util.concurrent.FutureTask $ Sync .innerRun (FutureTask/java: 268) na java.util.concurrent.FutureTask.run (FutureTask/Java: 54) na java.util.concurrent.ThreadPoolExecutor $ Worker.runTask (ThreadPoolExecutor.java:885) w java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:907) w java.lang.Thread.run (Thread.java:619)

+0

Czy możesz podać więcej informacji o swoim środowisku?Widziałem to dzieje się pod oknami podczas uruchamiania w powłoce cmd podczas próby oglądania logowania. – carson

+0

dzięki carson Dodałem więcej szczegółów do pytania –

+0

+1 dla "... usunąć go w oparciu o tę wiedzę ..." –

Odpowiedz

10

Możesz użyć AsyncAppendera, aby lepiej odłączyć rejestrator od dodających.

W systemie Windows kliknięcie w oknie konsoli spowoduje zatrzymanie konsoli, np. bufor standardowego zapełni się, a gdy programator konsoli pisze seryjnie, twoja aplikacja zawiesza się, dopóki nie zwolnisz konsoli (naciśnij klawisz Enter lub tak).

Rozważ użycie AsyncAppendera z log4j - przez większość czasu jest to dobry pomysł - jedyny problem w działaniu - bufor AsynAppender nie jest całkowicie spłukiwany przy wychodzeniu.

+0

Dzięki siddhadev użyłem własnego AsyncAppendera i przestałem używać rzeczy dodających konsolę, które działają teraz lepiej. –

9

Po pierwsze, uważam, że log4j zapisuje do plików i konsoli seryjnie, inaczej wszystkie twoje dzienniki byłyby uszkodzone. więc podczas gdy jeden wątek pisze inny wątek, który chce napisać, musi poczekać, aż drugi skończy. również, stdout może zablokować, jeśli cokolwiek jest z nim połączone, z drugiej strony, nie powoduje jego wyczerpania.

w systemie unix istnieje specjalny deskryptor pliku o nazwie stdout. po uruchomieniu aplikacji w konsoli stdout zostanie dołączony do konsoli. możesz także przekierować standardowe wyjście do innych plików. np .: java Blah>/dev/null. jest szansa, że ​​masz standardowe wyjście wskazujące na plik, który się wypełnia. na przykład rura jest plikiem i jeśli program na drugim końcu nie opróżnia rury, program piszący do rury ostatecznie zablokuje.

+0

Masz rację, ale nie rozumiem, dlaczego dodatek do konsoli jest taki, jaki jest. Dzięki –

+0

Logujesz się za dużo. Spróbuj zmniejszyć poziom dziennika dla niektórych rzeczy, które Cię nie interesują. –

+1

W jaki sposób dołączasz stdout? czy wskazuje na plik? do konsoli? czy tak się dzieje, jeśli wskażesz go w/dev/null? –