0

私は単純なプロデューサーを探しています-Javaでのコンシューマー実装であり、車輪の再発明をしたくありません

新しい同時実行パッケージといずれかのPipedクラスの両方を使用する例が見つかりませんでした

PipedInputStreamと新しいJava同時実行パッケージの両方をこのために使用する例はありますか?

そのようなタスクにPipedクラスを使用しないより良い方法はありますか?

4

1 に答える 1

5

BufferedOutputStreamあなたのタスクでは、単一のスレッドを使用し、データベースから読み取るときにを使用してファイルに書き込むだけで十分な場合があります。

バッファサイズとファイルに書き込まれるチャンクのサイズをより細かく制御したい場合は、次のようにすることができます。

class Producer implements Runnable {

    private final OutputStream out;
    private final SomeDBClass db;

    public Producer( OutputStream out, SomeDBClass db ){
        this.out = out;
        this.db = db;
    }

    public void run(){
        // If you're writing to a text file you might want to wrap
        // out in a Writer instead of using `write` directly.
        while( db has more data ){
            out.write( the data );
        }
        out.flush();
        out.close();
    }
}

class Consumer implements Runnable {

    private final InputStream in;
    private final OutputStream out;
    public static final int CHUNKSIZE=512;

    public Consumer( InputStream in, OutputStream out ){
        this.out = out;
        this.in = in;
    }

    public void run(){
        byte[] chunk = new byte[CHUNKSIZE];

        for( int bytesRead; -1 != (bytesRead = in.read(chunk,0,CHUNKSIZE) );;){
            out.write(chunk, 0, bytesRead);
        }
        out.close();
    }
}

そして、呼び出しコードで:

FileOutputStream toFile = // Open the stream to a file
SomeDBClass db = // Set up the db connection
PipedInputStream pi = new PipedInputStream(); // Optionally specify a size
PipedOutputStream po = new PipedOutputStream( pi );

ExecutorService exec = Executors.newFixedThreadPool(2);
exec.submit( new Producer( po, db ) );
exec.submit( new Consumer( pi, toFile ) );
exec.shutdown();
  • また、スローされる可能性のある例外をキャッチします。

これがすべての場合、を使用する利点はないことに注意してくださいExecutorService。エグゼキュータは、タスクが多い場合に役立ちます(タスクが多すぎて、すべてをスレッドで同時に起動することはできません)。ここでは、同時に実行する必要があるスレッドは2つしかないため、Thread#start直接呼び出すとオーバーヘッドが少なくなります。

于 2012-05-02T15:17:59.027 に答える