2017-05-30 1 views
0

J'utilise client http apache pour exécuter certaines demandes de publication sur un serveur cible, en écrivant le contenu à l'aide de flux canalisés. Donc, fondamentalement, à partir d'un client http thread est à lire de PipedInputStream et d'un autre thread, je suis en train d'écrire le contenu sur un PipedOutputStream.Le thread Java PipedInputStream est dans l'état BLOQUÉ sans autre thread détenant le verrou?

De temps en temps, j'obtiens des bourrages de threads et je vois beaucoup de threads bloqués sur la méthode java.io.PipedInputStream.read() exécutant la ligne wait(1000). L'état BLOCKED signifie que le thread de lecture attend pour récupérer le verrou après 1000 ms écoulé. Mais ce que je ne comprends pas, c'est pourquoi je ne vois pas de fil d'écriture pour tenir le verrou dans le vidage du fil. Qu'est-ce qui me manque et comment puis-je éviter d'avoir des threads bloqués?

Voici quelques lignes de l'intérieur fichier de vidage de fil:

Thread 7912: (state = BLOCKED) 
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise) 
- java.io.PipedInputStream.read() @bci=142, line=326 (Compiled frame) 
- java.io.PipedInputStream.read(byte[], int, int) @bci=43, line=377 (Compiled frame) 
- org.apache.http.entity.InputStreamEntity.writeTo(java.io.OutputStream) @bci=75, line=140 (Compiled frame) 
- org.apache.http.impl.execchain.RequestEntityProxy.writeTo(java.io.OutputStream) @bci=10, line=123 (Compiled frame) 
- org.apache.http.impl.DefaultBHttpClientConnection.sendRequestEntity(org.apache.http.HttpEntityEnclosingRequest) @bci=31, line=156 (Compiled frame) 
- org.apache.http.impl.conn.CPoolProxy.sendRequestEntity(org.apache.http.HttpEntityEnclosingRequest) @bci=5, line=162 (Compiled frame) 
- org.apache.http.protocol.HttpRequestExecutor.doSendRequest(org.apache.http.HttpRequest, org.apache.http.HttpClientConnection, org.apache.http.protocol.HttpContext) @bci=223, line=238 (Compiled frame) 
- org.apache.http.protocol.HttpRequestExecutor.execute(org.apache.http.HttpRequest, org.apache.http.HttpClientConnection, org.apache.http.protocol.HttpContext) @bci=25, line=123 (Compiled frame) 
- org.apache.http.impl.execchain.MainClientExec.execute(org.apache.http.conn.routing.HttpRoute, org.apache.http.client.methods.HttpRequestWrapper, org.apache.http.client.protocol.HttpClientContext,  org.apache.http.client.methods.HttpExecutionAware) @bci=714, line=271 (Compiled frame) 
- org.apache.http.impl.execchain.ProtocolExec.execute(org.apache.http.conn.routing.HttpRoute, org.apache.http.client.methods.HttpRequestWrapper, org.apache.http.client.protocol.HttpClientContext, org.apache.http.client.methods.HttpExecutionAware) @bci=447, line=184 (Compiled frame) 
- org.apache.http.impl.execchain.RetryExec.execute(org.apache.http.conn.routing.HttpRoute, org.apache.http.client.methods.HttpRequestWrapper, org.apache.http.client.protocol.HttpClientContext, org.apache.http.client.methods.HttpExecutionAware) @bci=39, line=88 (Compiled frame) 
- org.apache.http.impl.client.InternalHttpClient.doExecute(org.apache.http.HttpHost, org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) @bci=168, line=184 (Compiled frame) 
- org.apache.http.impl.client.CloseableHttpClient.execute(org.apache.http.client.methods.HttpUriRequest, org.apache.http.protocol.HttpContext) @bci=14, line=82 (Compiled frame) 
- org.apache.http.impl.client.CloseableHttpClient.execute(org.apache.http.client.methods.HttpUriRequest) @bci=6, line=107 (Compiled frame) 

Répondre

-1

Lorsque vous appelez lu sur InputStream il attendra jusqu'à ce qu'un OutputStream finira par obtenir les données. C'est pourquoi vous avez des bloks en attente. Donc, il ne s'agit pas d'écrire et de verrouiller, il s'agit de lire et d'attendre pendant que inputStream aura des données.

+0

S'il n'y a pas de données, le thread de lecture sera dans l'état 'RUNNABLE' ou' TIMED_WAITING' car il exécute la boucle while dans la méthode read ou exécute wait (long) depuis cette boucle. Être dans l'état BLOQUÉ signifie que l'autre thread a ce verrou, mais il n'y a pas un tel thread d'écriture dans le vidage du thread. –

+0

Les flux de sortie n'obtiennent pas de données, et il ne s'agit pas de "lire et attendre pendant que inputStream aura des données". Avec quoi et les fautes d'orthographe, cette réponse est à peine compréhensible, et erronée lorsqu'elle est compréhensible. – EJP

0

Lorsque vous appelez read() sur un PipedInputStream et le tampon est vide, il va bloquer dans wait() sur un objet jusqu'à ce que le PipedOutputStream écrit quelque chose et tout objet correspondant notifie le PipedInputStream est en attente. Ceci est juste le familier

synchronized (lock) 
{ 
    while (...) 
     lock.wait(); 
} 
modèle

, où wait() libère le verrou pour quelqu'un d'autre pour synchroniser et informer sur. Pourquoi est-ce que vous utilisez du tout un cours d'eau est un autre mystère. Ils ne sont qu'un jouet.

+0

Si le tampon est vide, l'état du thread de lecture dans la mémoire tampon sera «TIMED_WAITING» et non «BLOCKED». Et btw, que l'attente de 'PipedInputStream' a un délai d'expiration. Une fois ce délai expiré, le thread de lecture tente de récupérer le verrou qui a été libéré en exécutant la méthode wait, et s'il ne peut pas le prendre, il sera à l'état BLOQUÉ. S'il réussit, il sera dans l'état "RUNNIGN". Ceci est étrange, car cela signifie qu'il doit y avoir un autre thread (le thread d'écriture) qui détient ce verrou, mais il n'y a aucune trace dans le thread dump. –

+0

Je travaille sur un serveur proxy http en plus de 'apache mina'. Ce serveur reçoit donc un paquet d'octets, les décode dans un objet http, puis construit et exécute une autre requête sur un serveur cible. Donc, dans un thread, j'ouvre un flux vers le serveur cible en utilisant 'apache httpclient' qui enveloppe le' PipedInputStream' dans la requête, et d'un autre thread je suis en train de pomper les données en utilisant 'PipedOutputStream'. –

+0

Rien de tout cela n'explique pourquoi vous utilisez des flux canalisés en premier lieu. Je les ai utilisés exactement une fois, en 1997, et les ai enlevés presque immédiatement. – EJP