消费者生产者使用ExecutorService和PipedReader/PipedWriter(或PipedInputStream/PipedOutStream)的Java示例

消费者生产者使用ExecutorService和PipedReader/PipedWriter(或PipedInputStream/PipedOutStream)的Java示例,java,producer-consumer,executorservice,java.util.concurrent,Java,Producer Consumer,Executorservice,Java.util.concurrent,我正在寻找一个简单的Java生产者-消费者实现,不想重新发明轮子 我找不到同时使用新并发包和管道类的示例 是否有一个同时使用和新Java并发包的例子 对于这样的任务,有没有更好的方法不使用管道类?对于您的任务,在从数据库读取时,只使用单个线程并使用缓冲输出流写入文件就足够了 如果希望对缓冲区大小和写入文件的块大小进行更多控制,可以执行以下操作: class Producer implements Runnable { private final OutputStream out;

我正在寻找一个简单的Java生产者-消费者实现,不想重新发明轮子

我找不到同时使用新并发包和管道类的示例

是否有一个同时使用和新Java并发包的例子


对于这样的任务,有没有更好的方法不使用管道类?

对于您的任务,在从数据库读取时,只使用单个线程并使用
缓冲输出流写入文件就足够了

如果希望对缓冲区大小和写入文件的块大小进行更多控制,可以执行以下操作:

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
没有任何好处。当您有许多任务(太多而无法同时在线程中启动所有任务)时,执行器非常有用。在这里,您只有两个线程必须同时运行,因此直接调用
线程#start
将减少开销。

对于您的任务,只需使用一个线程,并在从数据库读取时使用
缓冲输出流写入文件就足够了

如果希望对缓冲区大小和写入文件的块大小进行更多控制,可以执行以下操作:

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
没有任何好处。当您有许多任务(太多而无法同时在线程中启动所有任务)时,执行器非常有用。在这里,您只有两个线程必须同时运行,因此直接调用
Thread\start
将减少开销。

您到底想实现什么?你提出了一个非常广泛的问题。如果我使用管道流,我不介意只启动一个线程。您是否只想使消费者和生产者的
可运行
s并将其提交给
ExecutorService
?该任务只需从数据库读取,然后以非阻塞/异步/缓冲方式写入文件,问题中提到的工具正是我认为适合这份工作的工具,如果有更简单/不同的方法,我很乐意hear@trutheality-是的,你到底想达到什么目的?你提出了一个非常广泛的问题。如果我使用管道流,我不介意只启动一个线程。您是否只想使消费者和生产者的
可运行
s并将其提交给
ExecutorService
?该任务只需从数据库读取,然后以非阻塞/异步/缓冲方式写入文件,问题中提到的工具正是我认为适合这份工作的工具,如果有更简单/不同的方法,我很乐意hear@trutheality-是的,差不多