JVM Tutorials - Herong's Tutorial Examples - Version 4.23, by Dr. Herong Yang
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
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
JRockit JVM 28.2.7 by Oracle Corporation
Memory Management and Garbage Collectors
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
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