How to stop a thread after it has completed the ru

2019-02-20 02:22发布

问题:

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.

I know something is wrong with the way I am using threads and Runnable object. I am new to them and can't seem to figure out how to fix it.

It errors with a java.lang.OutOfMemoryError: Java heap space error on the line worker.start() after a few seconds.

Here is my 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<Job> 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<Thread> threads = new ArrayList<Thread>();
    ArrayList<Job> ready = new ArrayList<Job>();
    while (x.isEmpty()!= true)
    {
        for(int i=0; i<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 < numThreads && i < 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 > 0);
}
    long endTime = System.nanoTime();
    long duration = endTime - startTime;
    return ("The Tasks took " + (duration/1000) + " seconds");
}


}

回答1:

You don't need to.. After thread has completed the run() method of Runnable, it should be completed. The OOM error you are facing is something to do with the logic inside the run() method of the Runnable.