title: Unexplained halt of execution
body: <p>I am working on a Java process that contains 2 threads: one for reading a file's contents and adding them in one shared blocking queue; and one for retrieving the lines from the blocking queue and sending them through the network (under a specified send rate). The two classes I have are the following:</p>
  
  <p><strong>Updated Code below</strong></p>
  
  <p>Producer Thread:</p>
  
  <pre><code>import java.io.BufferedReader;
  import java.io.File;
  import java.io.FileNotFoundException;
  import java.io.FileReader;
  import java.io.IOException;
  import java.util.concurrent.ArrayBlockingQueue;
  
  public class SourceFileProducer implements Runnable {
  
      private File file;
  
      private BufferedReader reader;
  
      private ArrayBlockingQueue&lt;String&gt; buffer;
  
      private String fileName;
  
      private String endMarker;
  
      public SourceFileProducer(ArrayBlockingQueue&lt;String&gt; buffer, 
              String endMarker, String fileName) {
          this.buffer = buffer;
          this.endMarker = endMarker;
          file = new File(fileName);
          if(file.exists()) {
              try {
                  reader = new BufferedReader(new FileReader(file));
              } catch (FileNotFoundException e) {
                  e.printStackTrace();
              }
          }
          this.fileName = fileName;
      }
  
      @Override
      public void run() {
          System.out.println("SourceFileProducer thread-" + Thread.currentThread().getId() + " initiating with source file: " + fileName);
          String line = "";
          try {
              while((line = reader.readLine()) != null) {
                  try {
                      buffer.put(line);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
              try {
                  buffer.put(endMarker);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              System.out.println("SourceFileProducer thread-" + Thread.currentThread().getId() + " scanned and buffered the whole file.");
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  }
  </code></pre>
  
  <p>and the Consumer thread:</p>
  
  <pre><code>import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.io.PrintWriter;
  import java.net.ServerSocket;
  import java.net.Socket;
  import java.util.concurrent.ArrayBlockingQueue;
  
  public class SourceFileConsumer implements Runnable {
  
      private ArrayBlockingQueue&lt;String&gt; buffer;
  
      private BufferedReader socketInput;
  
      private PrintWriter socketOutput;
  
      private Socket client;
  
      private ServerSocket serverSocket;
  
      private long checkpoint[] = null;
  
      private int rate[] = null;
  
      private String endMarker;
  
      public SourceFileConsumer(ArrayBlockingQueue&lt;String&gt; buffer, String endMarker, 
              ServerSocket serverSocket, Socket client, long checkpoint[], int rate[]) {
          this.buffer = buffer;
          this.endMarker = endMarker;
          this.client = client;
          try {
              socketOutput = new PrintWriter(client.getOutputStream(), true);
              socketInput = new BufferedReader(new InputStreamReader(client.getInputStream()));
          } catch (IOException e) {
              e.printStackTrace();
          }
          this.checkpoint = new long[checkpoint.length];
          this.rate = new int[rate.length];
          for(int i = 0; i &lt; checkpoint.length; i++) {
              this.checkpoint[i] = checkpoint[i];
              this.rate[i] = rate[i];
          }
          this.serverSocket = serverSocket;
      }
  
      @Override
      public void run() {
          String line = null;
          long start = System.currentTimeMillis();
          int index = 0;
          boolean fileScanFlag = true;
          while(fileScanFlag) {
              long startTimestamp = System.currentTimeMillis();
              long interval = (startTimestamp - start) / 1000L;
              if(interval &gt;= checkpoint[index]) {
                  if(index &lt; checkpoint.length - 1) {
                      if(interval &gt;= checkpoint[index + 1]) {
                          index += 1;
                          System.out.println("SourceFileConsumer thread-" + Thread.currentThread().getId() + 
                                  " progressed to checkpoint " + index + " with rate: " + rate[index]);
                      }
                  }
              }
              int counter = 0;
              while(counter &lt; rate[index]) {
                  try {
                      line = buffer.take();
                  } catch (InterruptedException e1) {
                      e1.printStackTrace();
                  }
                  if(line == endMarker) {
                      fileScanFlag = false;
                      break;
                  }
                  if(socketOutput != null &amp;&amp; socketOutput.checkError()) {
                      System.out.println("SourceFileConsumer Thread-" + Thread.currentThread().getId() + " detected broken link...");
                      try {
                          client = serverSocket.accept();
                          socketOutput = new PrintWriter(client.getOutputStream(), true);
                          socketInput = new BufferedReader(new InputStreamReader(client.getInputStream()));
                      } catch(IOException e) {
                          e.printStackTrace();
                      }
                      System.out.println("SourceFileConsumer Thread-" + Thread.currentThread().getId() + " re-established connection...");
                  }
                  if(socketOutput != null)
                      socketOutput.println(line);
                  counter += 1;
              }
              long endTimestamp = System.currentTimeMillis();
              if(endTimestamp - startTimestamp &lt;= 1000) {
                  System.out.println("thread-" + Thread.currentThread().getId() + " input rate: " + counter + 
                          ", wait time: " + (1000 - (endTimestamp - startTimestamp)));
                  try {
                      Thread.sleep((1000 - (endTimestamp - startTimestamp)));
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          }
          if(socketInput != null &amp;&amp; socketOutput != null &amp;&amp; client != null) {
              try {
                  socketInput.close();
                  socketOutput.close();
                  client.close();
              } catch(IOException e) {
                  e.printStackTrace();
              }
          }
          System.out.println("SourceFileConsumer Thread-" + Thread.currentThread().getId() + " transfer complete.");
      }   
  }
  </code></pre>
  
  <p>The problem is that, after a while, both threads hang and no tuples are sent. When I run a top command in my Linux machine, I see that the Java process, in which the two threads are running in, uses a really small amount of CPU time. Why is this happening? Is this a problem with starvation? I think that starvation can be avoided by using the <code>LinkedBlockingQueue</code>.</p>
  
  <p>Any hints?</p>
  
  <p>Thanks,
  Nick</p>