Details
-
Bug
-
Status: In Progress
-
Minor
-
Resolution: Unresolved
-
None
-
None
-
None
-
Windows
-
Patch Available
Description
According to J2SE specification
"File channels are safe for use by multiple concurrent threads."
But the following test demonstrates that FileChannel.write(ByteBuffer[]) sometimes works incorrectly when
some threads try to write bytes to the same channel.
Not all data are written to the file.
--------------fchTest.java--------------
import java.io.File;
import java.io.IOException;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.nio.channels.FileChannel;
import java.nio.ByteBuffer;
public class fchTest {
public static int N_TH = 20;
public static final int BUF_SIZE = 2000;
public static final int N_BUF = 20;
public static final int N_WRITES = 20;
boolean passed = true;
String fileName = "FileChannel.file";
FileChannel outChannel = null;
FileChannel inChannel = null;
public static void main(String[] args) {
try {
if (args.length > 0)
} catch (Throwable e) {
}
int res = new fchTest().test(args);
System.err.println(res == 104 ? "Test passed" : "Test failed");
}
public int test(String[] params) {
File f = null;
passed = true;
try {
f = new File(fileName);
if (f.exists())
outChannel = new FileOutputStream(f).getChannel();
inChannel = new FileInputStream(f).getChannel();
Thread[] t = new Thread[N_TH];
for (int i = 0; i < t.length; ++i) { t[i] = new thWriter(this); t[i].start(); }
for (int i = 0; i < t.length; ++i) { t[i].join(); }
} catch (Throwable t) { t.printStackTrace(); return 105; } finally {
try {
if (outChannel != null){ outChannel.close(); }
if (inChannel != null){ inChannel.close(); }
} catch (Throwable t){ t.printStackTrace(); }
if (f != null){ f.delete(); }
}
return (passed ? 104 : 106);
}
}
class thWriter extends Thread {
FileChannel outChannel = null;
fchTest base = null;
thWriter(fchTest base)
{ this.outChannel = base.outChannel; this.base = base; }public void run () {
try {
long allW = 0;
long allC = 0;
for (int i = 0; i < fchTest.N_WRITES; ++i) {
ByteBuffer[] bbb = createByteChunks();
for (int t = 0; t < bbb.length; t++)
long written = outChannel.write(bbb);
if (written != (long)((fchTest.BUF_SIZE)*fchTest.N_BUF))
allW+=written;
Thread.yield();
Thread.sleep(10);
}
System.err.println(this+" - after write: "allW" "+allC);
if (allW != allC)
outChannel.force(false);
} catch (Throwable e)
{ System.err.println(this+" unexpected exception " + e); e.printStackTrace(); base.passed = false; }}
ByteBuffer[] createByteChunks() {
ByteBuffer[] bb_arr = new ByteBuffer[fchTest.N_BUF];
byte [] bb = new byte[fchTest.BUF_SIZE];
for (int i = 0; i < bb.length; i++)
for (int i = 0; i < bb_arr.length; ++i)
{ bb_arr[i] = ByteBuffer.allocateDirect(bb.length).wrap(bb); }
return bb_arr;
}
}
----------------------------------------------------
Run this test several times and change the number of created threads
java fchTest
java fchTest 30
Output on RI:
==============
java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)
Thread[Thread-1,5,main] - after write: 800000 800000
Thread[Thread-11,5,main] - after write: 800000 800000
Thread[Thread-19,5,main] - after write: 800000 800000
Thread[Thread-17,5,main] - after write: 800000 800000
Thread[Thread-9,5,main] - after write: 800000 800000
Thread[Thread-13,5,main] - after write: 800000 800000
Thread[Thread-15,5,main] - after write: 800000 800000
Thread[Thread-7,5,main] - after write: 800000 800000
Thread[Thread-3,5,main] - after write: 800000 800000
Thread[Thread-0,5,main] - after write: 800000 800000
Thread[Thread-5,5,main] - after write: 800000 800000
Thread[Thread-16,5,main] - after write: 800000 800000
Thread[Thread-6,5,main] - after write: 800000 800000
Thread[Thread-12,5,main] - after write: 800000 800000
Thread[Thread-2,5,main] - after write: 800000 800000
Thread[Thread-8,5,main] - after write: 800000 800000
Thread[Thread-10,5,main] - after write: 800000 800000
Thread[Thread-4,5,main] - after write: 800000 800000
Thread[Thread-14,5,main] - after write: 800000 800000
Thread[Thread-18,5,main] - after write: 800000 800000
Test passed
Output on DRLVM:
==============
Apache Harmony Launcher : (c) Copyright 1991, 2006 The Apache Software Foundation or its licensors, as applicable.
java version "1.5.0"
pre-alpha : not complete or compatible
svn = r544707, (Jun 6 2007), Windows/ia32/msvc 1310, release build
http://harmony.apache.org
The GC did not provide gc_add_weak_root_set_entry()
Thread[Thread-9,5,main] Written: 33100 should be 40000 outChannel position: 6874000
Thread[Thread-20,5,main] - after write: 800000 800000
Thread[Thread-16,5,main] - after write: 800000 800000
Thread[Thread-8,5,main] - after write: 800000 800000
Thread[Thread-12,5,main] - after write: 800000 800000
Thread[Thread-22,5,main] - after write: 800000 800000
Thread[Thread-14,5,main] - after write: 800000 800000
Thread[Thread-18,5,main] - after write: 800000 800000
Thread[Thread-23,5,main] - after write: 800000 800000
Thread[Thread-11,5,main] - after write: 800000 800000
Thread[Thread-10,5,main] - after write: 800000 800000
Thread[Thread-24,5,main] - after write: 800000 800000
Thread[Thread-7,5,main] - after write: 800000 800000
Thread[Thread-15,5,main] - after write: 800000 800000
Thread[Thread-9,5,main] - after write: 793100 800000
Thread[Thread-6,5,main] - after write: 800000 800000
Thread[Thread-25,5,main] - after write: 800000 800000
Thread[Thread-17,5,main] - after write: 800000 800000
Thread[Thread-13,5,main] Written: 37700 should be 40000 outChannel position: 15872000
Thread[Thread-19,5,main] - after write: 800000 800000
Thread[Thread-13,5,main] - after write: 797700 800000
Thread[Thread-21,5,main] - after write: 800000 800000
Test failed
This bug causes the failure of the test
api.nio.channels.filechannel.FileChannelThrSafetyTest
from Reliability test suite https://issues.apache.org/jira/browse/HARMONY-2918
Attachments
Attachments
Issue Links
- blocks
-
HARMONY-4110 [M2] umbrella task for 98% pass rate of Reliability test - HARMONY-2918; no regression since M1
- Closed