使用PipedOutputStream时线程争用条件只会挂起

时间:2016-10-27 14:00:12

标签: java thread-safety java.util.concurrent java-threads

我正在使用管道输出流将OutputStream转换为InputStream,因为AWS java sdk不允许使用OutputStreams

在S3上放置对象

我使用下面的代码,然而,这将间歇性地挂起。此代码位于Web应用程序中。目前应用程序没有任何负载......我只是在我的个人计算机上试用它。

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()
 }

1 个答案:

答案 0 :(得分:2)

而不是烦恼于启动另一个线程的复杂性,实例化两个并发类,然后将数据从线程传递给线程,所有这些都只能解决所提供的JDK API中的一个小限制,你应该创建一个简单的专门化ByteArrayOutputStream

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

将其转换为输入流,无需复制。