FULL PRODUCT VERSION :
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Linux 2.4.22 i686
EXTRA RELEVANT SYSTEM CONFIGURATION :
Viewing applet using Mozilla 1.7
A DESCRIPTION OF THE PROBLEM :
When a caching download (ie getting a file using caches that is not already in the cache) is in progress, all other cached downloads block until this download is complete (even if the file they require _is_ in the cache)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Clear java cache
Download a small .au file (using URLConnection.getInputStream())
Start a thread downloading a large .au file
Try downloading the small .au file again - it will block until the large download is complete
Example applet that does this (apart from clearing the cache, which must be done manually) is at http://wwwb.forbidden.co.uk/~nae/cache_blocking/
Source code for this applet is below
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would expect the small file to download (from the cache) immediately.
ACTUAL -
The small file's getInputStream() blocks until the large file has finished downloading
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.*;
import java.io.*;
import java.net.*;
public final class downloader extends java.applet.Applet implements Runnable
{
volatile boolean killed = false;
boolean finished = false;
TextArea display = new TextArea();
static final String BigFile = "big";
static final String SmallFile = "small";
String suffix = ".au";
public final String getAppletInfo()
{ return "File downloader demo";
}
public final void init()
{
System.out.println("Applet loaded");
setLayout(new GridLayout(1,1));
add(display);
if (getParameter("suffix") != null)
suffix = getParameter("suffix");
}
public final void start() {
(new Thread(this)).start();
}
public void downloadFile(String fname)
{
try
{
display.append("Opening connection to file '"+fname+"'\n");
URL url = new URL(getCodeBase(),fname,null);
long startTime = System.currentTimeMillis();
URLConnection c = url.openConnection();
c.setUseCaches(true);
long connectTime = System.currentTimeMillis();
InputStream stream = c.getInputStream();
long streamTime = System.currentTimeMillis();
int bytesDownloaded = 0;
byte buffer[] = new byte[1024];
display.append("Got input stream to file '"+fname+"', downloading bytes\n");
while (!killed)
{
int length = stream.read(buffer, 0, 1024);
if (length == -1)
break;
bytesDownloaded += length;
}
long downloadTime = System.currentTimeMillis();
stream.close();
if (!killed)
{
int dr1 = streamTime==connectTime?-1:(int)((long)bytesDownloaded*8/(streamTime - connectTime)); // d/r if download happened at connect
int dr2 = downloadTime==streamTime?-1:(int)((long)bytesDownloaded*8/(downloadTime-streamTime)); // d/r if download happened at get
synchronized(display) {
display.append("Downloaded "+bytesDownloaded+" bytes from "+fname+"\n");
display.append("Times: getInputStream() : "+(streamTime - connectTime)+"ms ("+dr1+"kb/s)\n");
display.append(" download : "+(downloadTime - streamTime)+"ms ("+dr2+"kb/s)\n");
}
}
}
catch (Exception e) {
display.append("Threw exception '"+e.toString()+"'\n");
}
}
public final void run()
{
// Download small file to cache
downloadFile(SmallFile+suffix);
// Start downloading big file
new Thread(new Runnable()
{
public final void run() {
downloadFile(BigFile+suffix);
}
},"big download").start();
try {
Thread.sleep(100);
}
catch (InterruptedException e)
{
}
// Would expect small file to arrive immediately from cache
downloadFile(SmallFile+suffix);
}
public final void stop() {
killed = true;
}
public final void destroy() {
}
}
---------- END SOURCE ----------
2005-04-11 23:00:59 GMT
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Linux 2.4.22 i686
EXTRA RELEVANT SYSTEM CONFIGURATION :
Viewing applet using Mozilla 1.7
A DESCRIPTION OF THE PROBLEM :
When a caching download (ie getting a file using caches that is not already in the cache) is in progress, all other cached downloads block until this download is complete (even if the file they require _is_ in the cache)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Clear java cache
Download a small .au file (using URLConnection.getInputStream())
Start a thread downloading a large .au file
Try downloading the small .au file again - it will block until the large download is complete
Example applet that does this (apart from clearing the cache, which must be done manually) is at http://wwwb.forbidden.co.uk/~nae/cache_blocking/
Source code for this applet is below
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would expect the small file to download (from the cache) immediately.
ACTUAL -
The small file's getInputStream() blocks until the large file has finished downloading
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.*;
import java.io.*;
import java.net.*;
public final class downloader extends java.applet.Applet implements Runnable
{
volatile boolean killed = false;
boolean finished = false;
TextArea display = new TextArea();
static final String BigFile = "big";
static final String SmallFile = "small";
String suffix = ".au";
public final String getAppletInfo()
{ return "File downloader demo";
}
public final void init()
{
System.out.println("Applet loaded");
setLayout(new GridLayout(1,1));
add(display);
if (getParameter("suffix") != null)
suffix = getParameter("suffix");
}
public final void start() {
(new Thread(this)).start();
}
public void downloadFile(String fname)
{
try
{
display.append("Opening connection to file '"+fname+"'\n");
URL url = new URL(getCodeBase(),fname,null);
long startTime = System.currentTimeMillis();
URLConnection c = url.openConnection();
c.setUseCaches(true);
long connectTime = System.currentTimeMillis();
InputStream stream = c.getInputStream();
long streamTime = System.currentTimeMillis();
int bytesDownloaded = 0;
byte buffer[] = new byte[1024];
display.append("Got input stream to file '"+fname+"', downloading bytes\n");
while (!killed)
{
int length = stream.read(buffer, 0, 1024);
if (length == -1)
break;
bytesDownloaded += length;
}
long downloadTime = System.currentTimeMillis();
stream.close();
if (!killed)
{
int dr1 = streamTime==connectTime?-1:(int)((long)bytesDownloaded*8/(streamTime - connectTime)); // d/r if download happened at connect
int dr2 = downloadTime==streamTime?-1:(int)((long)bytesDownloaded*8/(downloadTime-streamTime)); // d/r if download happened at get
synchronized(display) {
display.append("Downloaded "+bytesDownloaded+" bytes from "+fname+"\n");
display.append("Times: getInputStream() : "+(streamTime - connectTime)+"ms ("+dr1+"kb/s)\n");
display.append(" download : "+(downloadTime - streamTime)+"ms ("+dr2+"kb/s)\n");
}
}
}
catch (Exception e) {
display.append("Threw exception '"+e.toString()+"'\n");
}
}
public final void run()
{
// Download small file to cache
downloadFile(SmallFile+suffix);
// Start downloading big file
new Thread(new Runnable()
{
public final void run() {
downloadFile(BigFile+suffix);
}
},"big download").start();
try {
Thread.sleep(100);
}
catch (InterruptedException e)
{
}
// Would expect small file to arrive immediately from cache
downloadFile(SmallFile+suffix);
}
public final void stop() {
killed = true;
}
public final void destroy() {
}
}
---------- END SOURCE ----------
2005-04-11 23:00:59 GMT