Question

D'abord quelques informations sur l'application. J'ai une application qui traite plusieurs tâches indépendantes en parallèle via un pool de threads. Le pool de threads est maintenant suspendu.

Ce qui suit est un extrait de mes vidages de threads. Tous mes threads du pool-2 sont BLOQUÉS par & "pool-2-thread-78 &". Il semble être bloqué en essayant d'écrire sur la console, ce que je trouve extrêmement étrange. Quelqu'un peut-il m'éclairer sur la situation?

MODIFIER : Détails de la plateforme version java " 1.6.0_07 " Environnement d'exécution Java SE (version 1.6.0_07-b06) Ordinateur virtuel client Java HotSpot (TM) (version 10.0-b23, mode mixte, partage)

Machine à double cœur, serveur Linux Ubuntu.

Il semble que le verrouillage se produise lors de l'écriture dans le flux d'impression. J'ai envisagé de ne supprimer que l'appendeur de console, mais je préférerais savoir pourquoi il bloque et le supprimer en fonction de ces informations. Dans le passé, le supprimer et voir si cela fonctionne est revenu me mordre:)

section pertinente de mon log4j

  

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

Extrait de vidage de thread

  

" pool-2-thread-79 " Id = 149 BLOQUÉ le   org.apache.log4j.spi.RootLogger@6c3ba437   appartenant à " 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 RUNNABLE à   java.io.FileOutputStream.writeBytes (Native   Méthode) à   java.io.FileOutputStream.write (FileOutputStream.java:260)     à   java.io.BufferedOutputStream.write (BufferedOutputStream.java:105)     - verrouillé < 0x6f314ba4 > (un java.io.BufferedOutputStream) à   java.io.PrintStream.write (PrintStream.java:430)     - verrouillé < 0xd5d3504 > (un 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)     - verrouillé < 0x6243a076 > (une 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)     - verrouillé < 0x45dbd560 > (a org.apache.log4j.ConsoleAppender) à l'adresse   org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders (AppenderAttachableImpl.java:65)     à   org.apache.log4j.Category.callAppenders (Category.java:203)     - verrouillé < 0x6c3ba437 > (un org.apache.log4j.spi.RootLogger) à l'adresse   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)

Était-ce utile?

La solution

Vous pouvez utiliser AsyncAppender pour mieux détacher l'enregistreur des appenders.

Sous Windows, si vous cliquez dans la fenêtre de la console, la console sera mise en pause, par exemple. le tampon stdout se remplira et, au fur et à mesure que l'appendeur de la console l'écrira en série, votre application se bloquera jusqu'à ce que vous relâchiez la console (appuyez sur Entrée, etc.).

Pensez à utiliser AsyncAppender avec log4j - la plupart du temps, c'est une bonne idée - seul problème: le tampon AsynAppender n'est pas vidé complètement à la sortie.

Autres conseils

D'abord, je pense que log4j écrit dans les fichiers et la console en série, sinon tous vos journaux seraient corrompus. Ainsi, lorsqu'un fil est en train d'écrire, un autre qui veut écrire doit attendre que l'autre soit fini. De plus, stdout peut bloquer si tout ce qui y est attaché à l’autre extrémité ne le vide pas.

Sous Unix, il existe un descripteur de fichier spécial appelé stdout. lorsque vous démarrez des applications sur la console, stdout sera attaché à la console. vous pouvez également rediriger stdout vers d'autres fichiers. ex: java Blah > / dev / null. il y a des chances que vous ayez stdout pointant vers un fichier en train de se remplir. Par exemple, un canal est un fichier et si le programme situé à l’autre extrémité ne draine pas le canal, le programme qui écrit sur le canal finira par se bloquer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top