2 votes

La condition de course de threads se bloque lors de l'utilisation de PipedOutputStream.

J'utilise des flux de sortie pipés pour convertir OutputStream a InputStream parce que le kit de développement Java d'AWS ne permet pas de mettre des objets sur S3 en utilisant OutputStreams

J'utilise le code ci-dessous, mais il se bloque par intermittence. Ce code se trouve dans une application Web. Actuellement, il n'y a pas de charge sur l'application... Je ne fais que l'essayer sur mon ordinateur personnel.

ByteArrayOutputStream os = new ByteArrayOutputStream();
PipedInputStream inpipe = new PipedInputStream();
final PipedOutputStream out = new PipedOutputStream(inpipe);
try {
   String xmpXml = "<dc:description>somedesc</dc:description>"
   JpegXmpRewriter rewriter = new JpegXmpRewriter();
   rewriter.updateXmpXml(isNew1,os, xmpXml); 
      new Thread(new Runnable() {
          public void run () {
              try {
                  // write the original OutputStream to the PipedOutputStream
                  println "starting writeto"
                  os.writeTo(out);
                  out.close();
                  println "ending writeto"
              } catch (IOException e) {
                  System.out.println("Some exception)
              }
          }
      }).start();
      ObjectMetadata metadata1 = new ObjectMetadata();
      metadata1.setContentLength(os.size());
      client.putObject(new PutObjectRequest("test-bucket", "167_sample.jpg", inpipe, metadata1));
    }
 catch (Exception e) { 
      System.out.println("Some exception")
 }
 finally {
    isNew1.close()
    os.close()
 }

2voto

Marko Topolnik Points 77257

Au lieu de s'embêter avec les complexités du démarrage d'un autre thread, de l'instanciation de deux classes concurrentes, puis du passage de données d'un thread à l'autre, tout cela pour ne résoudre qu'une limitation mineure de l'API fournie par le JDK, vous devriez simplement créer une simple spécialisation de la fonction ByteArrayOutputStream :

class BetterByteArrayOutputStream extends ByteArrayOutputStream {
    public ByteArrayInputStream toInputStream() {
        return new ByteArrayInputStream(buf, 0, count);
    }
}

Cela le convertit en un flux d'entrée sans copie.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X