Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6253678

Caching file download causes other cached downloads to block

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 6
    • 5.0
    • deploy
    • b42
    • x86
    • linux

      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

            ngthomas Thomas Ng (Inactive)
            gmanwanisunw Girish Manwani (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: