title: How to stop a thread after it has completed the runnable?
body: <p>I have a list of tasks and a limited number of threads.  The goal is to time how long the tasks take to finish using this number of threads.  </p>
  
  <p>I know something is wrong with the way I am using threads and <code>Runnable</code> object.  I am new to them and can't seem to figure out how to fix it. </p>
  
  <p>It errors with a  <code>java.lang.OutOfMemoryError: Java heap space error</code> on the line <code>worker.start()</code> after a few seconds.  </p>
  
  <p>Here is my code:</p>
  
  <pre><code>public class Tasks {
  
  static Timer timer; //times how long it takes to complete all tasks
  
  public static void main(String[] args) {
      Job t1 = new Sleep(5);
      Job t2 = new Sum(1000);
      Job t3 = new Sleep(3);
      Job t4 = new Sleep(10);
      Job t5 =  new Sum(10);
      Graph g = new Graph(5);
      g.getNumEdges();
      g.addEdge(t1, t2);
      g.addEdge(t2, t3);
      g.addEdge(t2, t4);
      g.addEdge(t3, t5);
      g.addEdge(t4, t5);
      //System.out.println(t5.getPredecessor());
      System.out.println(parseGraph(g, 2));
  
  }
  
  public static String parseGraph(Graph graph, int K)
  {
      long startTime = System.nanoTime();//start timer
      int numThreads = K;
      ArrayList&lt;Job&gt; x = graph.getNodes();
      //check for cycles
      CycleFinder dc = new CycleFinder(graph);
      if(dc.hasCycle()==true)
      {
          System.out.println(dc.cycle());
          return ("The graph has cycles and could not be parsed through.");
      }
      List&lt;Thread&gt; threads = new ArrayList&lt;Thread&gt;();
      ArrayList&lt;Job&gt; ready = new ArrayList&lt;Job&gt;();
      while (x.isEmpty()!= true)
      {
          for(int i=0; i&lt;x.size(); i++)
          {
              Job y= x.get(i);
              System.out.println(y);
              if(y.getComplete()== true)
              {
                  ready.remove(y);
                  graph.removeNode(y);
                  x.remove(y);
              }
              if(y.getPredecessor().isEmpty() || y.getPredecessor() ==null)
                  ready.add(y);
          }
          for (int i = 0; i &lt; numThreads &amp;&amp; i &lt; ready.size(); i++) {
              System.out.println("test");
              Runnable task = new MyRunnable(ready.get(i));
              Thread worker = new Thread(task);
              worker.setName(String.valueOf(i));
              worker.start();
              threads.add(worker);
            }
         //int running = 0;
         //do {
         //running = 0;
            //for (Thread thread : threads) {
              //if (thread.isAlive()) {
               // running++;
             // }
           // }System.out.println("We have " + running + " running threads. ");
         // } while (running &gt; 0);
  }
      long endTime = System.nanoTime();
      long duration = endTime - startTime;
      return ("The Tasks took " + (duration/1000) + " seconds");
  }
  
  
  }
  </code></pre>