Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restarting a java Thread

I was wondering why The ExecutorService can actually execute the same Thread multiple times. Because the usual lifecycle of a thread ends on TERMINATED afaik..

So,

public class TestThread extends Thread {

  AtomicInteger counter = new AtomicInteger(0);
  @Override
  public void run() {
    System.out.printf("%d\n", counter.addAndGet(1));
  }

  public static void main(String[] args) throws InterruptedException {
    ExecutorService es = Executors.newCachedThreadPool();
    TestThread t = new TestThread();

    es.execute(t);
    es.execute(t);

    es.shutdown();
  }
}

this works where i would actually expect an illegal state exception like in this case:

t.start();
t.start(); =>BAM!

Help much appreciated to unravel the magic behind the execute!

like image 713
Liebertee Avatar asked Dec 05 '14 10:12

Liebertee


People also ask

What is the use of thread stop () method in Java?

This method is used if you want to stop the thread execution and start it again when a certain event occurs. This method allows a thread to temporarily cease execution. The suspended thread can be resumed using the resume () method.

How to restart a dead thread in Java?

How can dead thread be restarted in Java? 1 New − A new thread begins its life cycle in the new state. ... 2 Runnable − After a newly born thread is started, the thread becomes runnable. ... 3 Waiting − Sometimes, a thread transitions to the waiting state while the thread waits for another thread to perform a task. ... More items...

How to start/restart a thread?

To start or restart (once a thread is stopped, you can't restart that same thread, but it doesn't matter; just create a new Thread instance): // Create your Runnable instance Task task = new Task (...); // Start a thread and run your Runnable Thread t = new Thread (task);

How do I run a thread in a separate thread in Java?

Both are in the java.lang package so you don’t have to use import statement. Then you put the code that needs to be executed in a separate thread inside the run () method which is overridden from the Thread/Runnable. And invoke the start () method on a Thread object to put the thread into running status (alive).


4 Answers

The ExecutorService.execute(Runnable) wraps them with new Thread instances. If you also print the thread id,

@Override
public void run() {
    System.out.printf("%d %d%n", counter.addAndGet(1),
        Thread.currentThread().getId());
}

You will see two different Thread(s) are running. For example,

1 10
2 11
like image 132
Elliott Frisch Avatar answered Sep 30 '22 18:09

Elliott Frisch


An ExecutorService does not ever re-start a Thread. A Thread can never be re-started.

An ExecutorService is a thread pool. It manages a set of long-running threads, and each thread is capable of performing many tasks.

When your code calls es.submit(r) for some ExeuctorService, es, and some Runnable, r; the submit function adds your runnable to a blocking queue.

Each of the threads managed by the ExecutorService has a run() method that looks like this:

public void run() {
    while (true) {
        Runnable task = queue.take();
        task.run();
    }
}

Of course really, it's more complicated than that because of exceptions and because of the shutdown() mechanism, but that's the basic idea. The pool threads basically run forever, waiting for tasks to perform.

like image 24
Solomon Slow Avatar answered Sep 30 '22 16:09

Solomon Slow


The start() method of your Thread object isn't invoked twice, not even once actually: only the Runnable interface of your object is used. Actual Threads are created with each execute(), each delegating to your run() method.

like image 41
geert3 Avatar answered Sep 30 '22 16:09

geert3


You can not restart thread, but you can detect threads that were used multiple times;)

Test code:

package com.stackoverflow.test;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

public class TestOfCachedThreadPool {
  private static final int AMOUNT = 1000000;

  private static final class TestThread implements Runnable {
    private Map<Long, Long> mapOfUsage;

    private TestThread(Map<Long, Long> mapOfUsage) {
      this.mapOfUsage = mapOfUsage;
    }

    @Override
    public void run() {
      synchronized (mapOfUsage) {
        Long numberOfThreads=mapOfUsage.get(Thread.currentThread().getId());
        if(numberOfThreads==null){
          mapOfUsage.put(Thread.currentThread().getId(), 1l);
        }else{
          mapOfUsage.put(Thread.currentThread().getId(), ++numberOfThreads);
        }
      }

    }
  }

  public static void main(String[] args) {
    ThreadFactory threadFactory = Executors.defaultThreadFactory();
    final Map<Long, Long> mapOfUsage = new HashMap<>(AMOUNT * 2);
    ExecutorService service = Executors.newCachedThreadPool();
    for(int i=0;i<AMOUNT;i++){
      service.execute(threadFactory.newThread(new TestThread(mapOfUsage)));
    }
    for(Map.Entry<Long, Long> entry: mapOfUsage.entrySet()){
      if(entry.getValue()>1){
        System.out.println("Thread with id "+entry.getKey() +" was used "+entry.getValue()+ " times");
      }
    }
  }
}

Output:

Thread with id 9 was used 27198 times

Thread with id 11 was used 1810 times

Thread with id 13 was used 1294 times

Thread with id 15 was used 3347 times

Thread with id 17 was used 6709 times

Thread with id 19 was used 7259 times

Thread with id 21 was used 39335 times

Thread with id 23 was used 13552 times

Thread with id 25 was used 535 times

Thread with id 27 was used 19533 times

Thread with id 29 was used 113495 times

Thread with id 31 was used 62713 times

Thread with id 35 was used 94103 times

Thread with id 33 was used 53641 times

Thread with id 5328 was used 18922 times

Thread with id 16388 was used 28501 times

Thread with id 16384 was used 114677 times

Thread with id 16386 was used 39 times

Thread with id 16698 was used 60450 times

Thread with id 123096 was used 19944 times

Thread with id 123102 was used 60961 times

Thread with id 123115 was used 24246 times

Thread with id 275492 was used 108399 times

Thread with id 275490 was used 11973 times

Thread with id 380143 was used 10433 times

Thread with id 363358 was used 55989 times

Thread with id 692626 was used 6016 times

Thread with id 909079 was used 25782 times

Thread with id 965801 was used 32 times

Thread with id 948919 was used 1782 times

Thread with id 948872 was used 4 times

Thread with id 938802 was used 24 times

Thread with id 923558 was used 7302 times

like image 42
Maksym Avatar answered Sep 30 '22 16:09

Maksym