简体   繁体   中英

Two threads writing to the same file

I have multiple threads (let's say two, for now), each of which retrieves an HTML page and writes its content to a file. The caveat is that each thread wants to write to the same output file. The class with the run() method is a static inner class. The approach I would like to take is to have each thread put the content it wants to write into a queue. THEN, after the thread is finished (or all the threads have finished), to iterate over the queues and print the contents to the file. I'm not sure how to implement this. Again, the class that implements the runnable interface is static. I'm not well-versed in concurrency and not necessarily looking to do anything fancy. Any suggestions for a simple implementation?

You could use the BlockingQueue from the java.util.concurrent package. Each of your threads would put its output into the queue, and a third thread would get the elements out of the queue and write them to the file. On the API page for Blocking Queue is an example that you should be able to use for your implementation. You only need to provide the implementation for produce and consume and you are done.

You can use a single threaded ExecutorService. This can be used to write the data as it is produced (rather than having to wait.

static final ExecutorService logger = Executors.newSingleThreadExecutor();

static void writeToFile(final FileOutputStream fos, final String text) {
    logger.execute(new Runnable() {
        public void run() {
            try {
                fos.write(text.getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });
}

您也可以使用synchronized块。

Well, based on your description, this is how I think your producers should look:

private static final int CAPACITY = 10; // whatever you like here.
private static Object locker = new Object();
private static Queue<String> queue = new ArrayBlockingQueue<String>(CAPACITY);

private static class ThreadTask implements Runnable {

    @Override
    public void run() {

        // retrieve page            
        // add result to queue
    }       
}

Of course, you can execute these ThreadTasks in an Executor, in order to better use the system resources and also your consumer thread can run simultaneously with the producers if you implement a producer-consumer queue system.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM