FileEditor.java - I/O Intensive Process

This section describes a thread productivity testing program, FileEditor.java, that repeats a work unit of reading data from a file and writing it back. It is a good example of I/O intensive process.

After looking at the CPU usage impact of multi-thread CPU intensive applications, we can now look at the disk I/O usage impact of multi-thread I/O intensive applications.

Here is the source code of FileEditor.java, which represents a thread to read data from a file and write it back repeatedly:

/* FileEditor.java
 * Copyright (c) 2014, HerongYang.com, All Rights Reserved.
 */
import java.io.*;
import java.util.*;
public class FileEditor extends Thread {
   public int fileSize; // The size of the file to work on
   public String fileName; // The name of the file
   public long jobCount; // The number of jobs done so far
   public int myCheckSum; // The checksum of the file
   public int firstByte; // The first byte of the file
   public static void main(String[] a) {
      int size = 1000;
      String name = "FileEditor.dat";
      long interval = 1; // Monitoring interval in seconds
      if (a.length>0) size = Integer.parseInt(a[0]);
      if (a.length>1) name = a[1];
      System.out.println("File size: "+size);

      // Initializing the data file
      byte[] data = new byte[size];
      Random r = new Random();
      r.nextBytes(data);
      try {
         FileOutputStream fos = new FileOutputStream(name);
         fos.write(data);
         fos.close();
      } catch (Exception e) {
      	 System.out.println(e.toString());
      	 return;
      }
      
      FileEditor t = new FileEditor(size, name);
      t.start();
      int i = 0;
      long startTime = System.currentTimeMillis();
      System.out.println(
         "Time, Count, Productivity, CheckSum, firstByte");
      while (true) {
         try {
            sleep(interval*1000);
         } catch (InterruptedException e) {
            System.out.println("Monitor interrupted.");
         }
         long curTime = System.currentTimeMillis();
         long duration = (curTime - startTime)/1000;
         long productivity = t.jobCount/duration;
         System.out.println(duration+", "+t.jobCount
            +", "+productivity+", "+t.myCheckSum+", "+t.firstByte);
      }
   }
   public FileEditor(int size, String name) {
      fileSize = size;
      fileName = name;
      jobCount = 0;
      myCheckSum = 0;
      firstByte = 0;
   }
   public void run() {
      byte[] buffer = new byte[fileSize];
      try {
         while (true) {
            FileInputStream fis = new FileInputStream(fileName);
            int bytes = fis.read(buffer);
            fis.close();
            long sum = 0;
            for (int i=0; i<fileSize; i++) {
                sum = (sum+(buffer[i]&0x00FF))%Integer.MAX_VALUE;
            }
            myCheckSum = (int)sum;
            firstByte = buffer[0]&0x00FF;
            FileOutputStream fos = new FileOutputStream(fileName);
            fos.write(buffer,1,fileSize-1);
            fos.write(buffer,0,1);
            fos.close();
            jobCount++;
         }
      } catch (Exception e) {
      	 System.out.println(e.toString());
      	 return;
      }     
   }
}

Some notes on FileEditor.java:

FileEditor.java seems to be working correctly, as you can see from the following test results. It shows that 4 random bytes were used in the data file: 78, 39, 230, 197, and the sum is 544.

C:\>"\Program Files\java\jdk1.7.0_45\bin\javac" FileEditor.java

C:\>"\Program Files\Java\jdk1.7.0_45\bin\java" FileEditor 4
File size: 4
Time, Count, Productivity, CheckSum, firstByte
1, 3104, 3103, 544, 230
2, 5760, 2880, 544, 197
3, 7415, 2471, 544, 230
4, 10133, 2533, 544, 78
5, 13557, 2711, 544, 78
6, 15178, 2529, 544, 39
7, 18899, 2699, 544, 230
8, 20687, 2585, 544, 230
9, 23472, 2608, 544, 197
10, 26679, 2667, 544, 230
11, 30381, 2761, 544, 197
12, 32760, 2730, 544, 197
13, 36462, 2804, 544, 39
14, 38472, 2748, 544, 197
15, 40940, 2729, 544, 197
16, 44014, 2750, 544, 39
...

But when running it again with a file size of 10, I got an exception:

C:\>"\Program Files\Java\jdk1.7.0_45\bin\java" FileEditor 10
java FileEditor 10
File size: 10
Time, Count, Productivity, CheckSum, firstByte
1, 832, 832, 1472, 99
2, 2273, 1136, 1472, 136
3, 3959, 1319, 1472, 102
4, 5674, 1418, 1472, 129
5, 6716, 1343, 1472, 94
6, 8357, 1392, 1472, 231
7, 9337, 1333, 1472, 231
8, 10794, 1349, 1472, 129
9, 11877, 1319, 1472, 231
10, 12827, 1282, 1472, 231
...
43, 55835, 1298, 1472, 94
44, 56922, 1293, 1472, 99
45, 58131, 1291, 1472, 218
java.io.FileNotFoundException: FileEditor.dat (The requested 
operation cannot be performed on a file with a user-mapped section
open)

What's wrong with FileEditor.java? I am reading and writing to the same file repeatedly. But it is always closed before open it again. See next section for more details on this issue.

Last update: 2014.

Table of Contents

 About This Book

 Downloading and Installing JDK 1.8.0 on Windows

 Downloading and Installing JDK 1.7.0 on Windows

 java.lang.Runtime Class - The JVM Instance

 java.lang.System Class - The Operating System

 ClassLoader Class - Class Loaders

 Class Class - Class Reflections

 Sun's JVM - Java HotSpot VM

 JRockit JVM 28.2.7 by Oracle Corporation

 JVM Runtime Data Areas

 Memory Management and Garbage Collectors

 Garbage Collection Tests

 JVM Stack, Frame and Stack Overflow

 Thread Testing Program and Result

 CPU Impact of Multi-Thread Applications

I/O Impact of Multi-Thread Applications

FileEditor.java - I/O Intensive Process

 FileEditor2.java - Avoiding FileNotFoundException

 MultithreadingIoRunner.java - Multiple I/O Threads

 Running Multiple I/O Threads on JRockit

 CDS (Class Data Sharing)

 Micro Benchmark Runner and JVM Options

 Micro Benchmark Tests on "int" Operations

 Micro Benchmark Tests on "long" Operations

 Micro Benchmark Tests in JIT Compilation Mode

 Micro Benchmark Tests on "float" and "double" Operations

 Outdated Tutorials

 References

 PDF Printing Version