2

I made a runnable class and created a thread but with a unique name but when I send this thread though executor.scheduleAtFixedRate it creates its own thread and I do not understand why is it?

I tried to read here but still, I do not understand this: https://www.codejava.net/java-core/concurrency/java-concurrency-scheduling-tasks-to-execute-after-a-given-delay-or-periodically

public class Main {

    public static void main(String[] args) throws ClassNotFoundException {
        ScheduledExecutorService executor =
                Executors.newSingleThreadScheduledExecutor();
        Runnable runnable = new AutoUpdater();
        Thread thread = new Thread(runnable, "MyThread");
        executor.scheduleAtFixedRate(thread, 0, 24, TimeUnit.HOURS);
    }
}

public class AutoUpdater implements Runnable {
    public void run() {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + " is running...");
        System.out.println("Thread ended.\n");
    }
}

It should print the name MyThread but the output is:

pool-1-thread-1

and it should be maybe something like this :

pool-1-MyThread-1
Michał Krzywański
  • 15,659
  • 4
  • 36
  • 63
David
  • 145
  • 1
  • 3
  • 13
  • 1
    The scheduler has its own threads it uses to execute tasks. Your thread object is just providing the code to be run, but not the name. – Hitobat Aug 04 '19 at 11:46
  • Can I change scheduler own threads name? and is it right to send a thead though executor? Maybe it should be executor.scheduleAtFixedRate(runnable, 0, 24, TimeUnit.HOURS); ?? – David Aug 04 '19 at 11:49

2 Answers2

1

The thing is that Executors.newSingleThreadScheduledExecutor() creates a pool which has it's own threads internally.

When you look at ScheduledExecutorService::scheduleAtFixedRate it takes Runnable as first argument. And this Runnable will be run by some thread from the pool. Notice that Thread implements Runnable and you pass a Thread instance to scheduleAtFixedRate method so this thread's run method will be invoked by some other thread but the thread that you passed wil not be started. Generally to avoid any misconceptions you should pass simple Runnable here which will represent work that needs to be done.

If you want to change names of threads from this pool you would have to provide custom ThreadFactory which will be used by the pool to create new threads :

ThreadFactory threadFactory = runnable -> new Thread(runnable, "MyThreadName");

ScheduledExecutorService executor =
            Executors.newSingleThreadScheduledExecutor(threadFactory);

EDIT :

For Java versions < 8 we could simply create new class implementing ThreadFactory interface :

class MyThreadFactory implements ThreadFactory {
    @Override
    public Thread newThread(Runnable runnable) {
        return new Thread(runnable, "MyThreadName");
    }
}

and then pass it :

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(new MyThreadFactory());
Michał Krzywański
  • 15,659
  • 4
  • 36
  • 63
0

The executor service is creating it for you. If you wish to override the naming of threads you can set options in the executor service. See Naming threads and thread-pools of ExecutorService

Michiel Leegwater
  • 1,172
  • 4
  • 11
  • 27
  • is it right to send a thead though executor? Maybe it should be executor.scheduleAtFixedRate(runnable, 0, 24, TimeUnit.HOURS); ?? – David Aug 04 '19 at 11:53