针对消费者生产者使用ExecutorService和PipedReader/PipedWriter(或PipedInputStream/PipedOutputStream)的Java示例 [英] Java example of using ExecutorService and PipedReader/PipedWriter (or PipedInputStream/PipedOutputStream) for consumer-producer

查看:92
本文介绍了针对消费者生产者使用ExecutorService和PipedReader/PipedWriter(或PipedInputStream/PipedOutputStream)的Java示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一个简单的生产者-Java中的使用者实现,并且不想重新发明轮子

我找不到同时使用新的并发包和两个Piped类的示例

是否有一个同时使用 PipedInputStream 以及为此使用的新Java并发包?

是否有一种更好的方法,而无需将Piped类用于此类任务?

解决方案

对于您的任务,仅使用一个线程并在您从数据库中读取时使用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没有任何好处.当您有许多任务(太多任务无法同时在线程中启动所有任务)时,执行程序就很有用.在这里,只有两个线程必须同时运行,因此直接调用Thread#start会减少开销.

I'm looking for a simple producer - consumer implementation in Java and don't want to reinvent the wheel

I couldn't find an example that uses both the new concurrency package and either of the Piped classes

Is there an example for using both PipedInputStream and the new Java concurrency package for this?

Is there a better way without using the Piped classes for such a task?

解决方案

For your task it might be sufficient to just use a single thread and write to the file using a BufferedOutputStream as you are reading from the database.

If you want more control over the buffer size and the size of chunks being written to the file, you can do something like this:

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

And in the calling code:

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

  • Also catch any exceptions that might be thrown.

Note that if this is all you're doing, there isn't any advantage to using an ExecutorService. Executors are useful when you have many tasks (too many to launch all of them in threads at the same time). Here you have only two threads that have to run at the same time, so calling Thread#start directly will have less overhead.

这篇关于针对消费者生产者使用ExecutorService和PipedReader/PipedWriter(或PipedInputStream/PipedOutputStream)的Java示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆