Java Concurrent Read & write files

Source: Internet
Author: User

Recently looking at Brian Goetz's <<java concurrent Combat >>, the book has two versions, the electronic industry publishing house is a bad translation, it is recommended to use the mechanical industry press published books.

When I saw the 34th chapter, I suddenly thought of multithreading read-write files, and encountered some problems in the book

1, how to ensure the security of the composite object?

2, how to judge the constraint condition of invariance

3, how do I synchronize with the Synchronized keyword and the lock?

Here is a piece of code that reads data from source and writes it to the target file by multithreading

Ideas:

1, how to Read/write file?

2, how to design reader class?

3, does the reader class need state to describe? How are state variables synchronized?

4, how to ensure that the current thread can accurately read the current segment?

Code Overview:


package org.mushroom.multithread;import java.io.closeable;import java.io.file;import  java.io.ioexception;import java.io.randomaccessfile;import java.util.objects;import  java.util.concurrent.atomic.atomiclong;/** *  points: * 1,  divides a file into &nbsp, and the size is  {@link  Reader#segmentLength}   {@link  Reader#segments}  files  * , each thread reads pure  Block to read the data, the blocks being accessed are tagged with {@link  reader#segment}  *&nbsp, and the global variable 1. * 2,  multiple threads is final {@ link reader#source}, final {@link  reader#target} and  * {@link  reader#segment}, Need to ensure the security of these variables  */public class Reader implements Runnable {     Private static final int byte = 1024;    private static  final long negative_one = -1l;    private static final  long zero = 0l;    private static final long one = 1l;     //  Global variables   for multithreaded access block     private final atomiclong segment  = new atomiclong (negative_one);    //  Single File size      private final int segmentlength = 30 * byte * byte;     //  Original File     private final File source;     //  file     private final file target;    /after copying The number of blocks after the/  file is divided     private final long segments;    //   Last piece of file actual size     private final long remains;     Public reader (String sourcepath, string targetpath)  throws ioexception {     &nbsP;   this.source = new file (SourcePath);         this.target = new file (TargetPath);         if  (!this.target.exists ())  {             This.target.createNewFile ();        }         this.remains =  (This.source.length ()  % segmentlength);         //If the remainder is not 0,  then one more block is needed to store the extra bytes, otherwise it will be lost          if  (This.remains != zero)  {             this.segments = this.source.length ()  / segmentLength +  one;        } else {              this.segments = sourcepath.length ()  / segmentLength;         }    }    /**     *  run:     * 1, while true:  the current block is not accessed,  from {@link  reader# SEGMENT&NBSP;=&NBSP;0} started the first visit to      * 2, {@link  reader#readblock ( Randomaccessfile, long)} reads data from the file and returns  byte[]     * 3, {@link   Reader#writeblock (Randomaccessfile, byte[], long)}, the buffer is written to the file after setting the position      * /    public void run ()  {         Randomaccessfile reader = null;        randomaccessfile  writer = null;        try {         &nBsp;   reader = new randomaccessfile (source,  "R");             writer = new randomaccessfile (target,  "RW" );            long position = -1l;             //Loop count Current segment,  multiple threads can be modified              while  (position =  Segment.incrementandget ())  < segments)  {                 final byte[] bytes = readblock (Reader,  position);                 writeblock (writer, bytes, position);             }        } catch  (ioexception e)  {             e.printstacktrace ();         }  finally {            close (writer);             close (reader);         }    }    private void writeblock ( Randomaccessfile writer, byte[] bytes, long position)  throws IOException  {        writer.seek (position * segmentlength);         writer.write (bytes);    }     /**     * 1, reader set POSITION&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;*&NBSP;2,   Creating a buffered array      * 3,  writes data to byte[]     * 4,  returns buffer array       *     *  @return  position  for  {@link  randomaccessfile# Write (byte[])} using      */    private byte[] readblock ( Randomaccessfile reader, long position)  throws IOException {         reader.seek (position * segmentlength);         final byte[] bytes = new byte[getwritelength (position)];         reader.read (bytes);         return bytes;    }    /**     *  Get current byte[] The actual writable length may be {@link  Reader#segmentLength}  or  {@link  Reader#remains}      */  &Nbsp; private int getwritelength (long position)  throws IOException {         if  (Position == segments + negative_one  && remains > zero)  {             return  (int)  remains;        }         return segmentLength;    }     /**     *  Common interface method for closing a stream      *      *  @param  closeable     */    private  void close (closeable closeable)  {        try  {            if  (Objects.nonnull ( closeable))  {                closeable.close ();             }        }  catch  (ioexception e)  {             E.printstacktrace ();         }    }}

Test code: Note that JUnit is powerless with multithreaded testing, it is recommended to use groboutils or simply the Main method

package  org.mushroom.multithread;import java.io.IOException;public class ReaderTest {     public static void main (String[] args)  throws ioexception  {        final String source =  "";         final String target =  "";         reader reader = new reader (Source, target);         new thread (reader). Start ();         new thread (reader). Start ();         new thread (reader). Start ();         new thread (reader). Start ();     }} 

How to resolve:

1, multi-threaded read files need to read data from different places, so the normal stream does not meet the requirements, so choose Java.io.RandomAccessFile It can be arbitrarily set file cursor. and contains Read&write way

2,①reader&writer Design

Multithreaded execution is the reader class of the Run method, so each thread must have its own independent reader&writer, so reader&writer must be thread-private, that is, the need to reader& In the writer wrapper thread, the reader&writer between threads cannot be shared.

② how to deal with Source&target?

each thread handles its own block of responsibility, and the final block is a complete target. That is, the source is divided into segment blocks of size segment length, but note that the actual valid data length of the last segment block is not segment length.

③ Other domain design

Requires two file to describe source&target;

Two variables are required to describe how many segments the source is divided into and the size of the segment segmentlength;

A variable is required to describe the size of the last piece of remain;

A shared variable segment is required to describe the file status of the source file;

3, the source file needs a segment variable to describe its status as multithreaded, that is, where the current thread is being processed. And those that haven't been processed yet.

4,thread read segment can use a java.util.concurrent.atomic. A variable of type Atomiclong describes it (that is, the main description of the current block is the number of blocks), the Atomiclong class of the increment/decrement operation is thread-safe. So the location of each block read is safe.


This article is from the "Small mushroom blog Big World" blog, please be sure to keep this source http://smallmushroom.blog.51cto.com/9474297/1862018

Java Concurrent Read & write files

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.