Threadpool re-use of threads - java

I know this topic has been asked a lot, but im not sure about one detail.
Now threadpool doesnt let a thread die after completing a task, and reuses it later on as needed (as it is said here, here, etc)
But let say my runnable has variables in the constuctor -
MyRunnable(int a){
this.a = a;
}
then, when we try to run the Runnable with a Executors.newFixedThreadPool (or something similar), we say
executor.execute(new MyRunnable(a)); // executor being Executors.newFixedThreadPool
now if variable 'a' is different in every execute, can Threadpool really reuse it later?
I cant really understand how that would work, but i never seen 'Threadpool reuses threads except...', hence the confusion.

No, neither the Runnable you submit, nor the variables related to it, will be reused.
I think you mis-understood Thread and Runnable, they are different things. A Runnable is just normal object, execept its run method will be executed when you create a new thread with it. You can check this question.
The re-use of thread does not mean the re-use of Runnable, it means the thread keeps executing different Runnables.
When you create a Thread with a Runnable, and start this thread like this:
new Thread(new Runnable()).start()
the run() method of this Runnale will be executed, and after the run() exiting, this Thread will terminate too.
But, the Runnbale you submit to the ThreadPoolExecutor is not the one in code above to construct the thread.
Briefly, threads in ThreadPoolExecutor are created like this:
Runnable worker = new Runnable() {
#Override
public void run() {
Runnable firstTask = getFirstTask(); // the first runnable
firstTask.run();
Runnable queuedTask;
while ( (queuedTask = getTaskFromQueue()) != null) { // This could get blocked
queuedTask.run();
}
}
};
new Thread(worker).start();
Note, the Runnable used to initate the thread is not the one you submitted to the pool.
When you submit new Runnable, the thread pool will check if it need to create new thread(based on the argument like corePoolSize).
If it is necessary, then it create a new Worker with this Runnable as FirstTask, and create a new thread with this Worker and start it.
If not, then it put the Runnbale in a queue. When there are free threads, they will check this queue and take tasks from it.

So, from my point how the thread pool working algorithm would be similar and looks like below
while (check if the pool is not shutdown) {
Runnable task = pool.fetchTaskFromQueue(); // fetch the Task from the queue. In your case it object of MyRunnable class
task.run(); // call the run() of MyRunnable object
}
Thread pool resues the Thread, not the Runnable/ Callable implementation. So, as per thread pool, it does reuse your variable a.

Related

All methods in runnable class run on a seperate thread or only run() method? Java

Let's say I have a runnable class with two methods:
class ExampleClass implements Runnable {
public void shutdown()
{
currentThread().interrupt();
}
public void run(){
while(!currentThread().isInterrupted()){
System.out.println("thread is running...");
}
}
And I go and implement the class somewhere like so and pass it to a thread:
ExampleClass object = new ExampleClass();
Thread sideThread = new Thread( object, "Side Thread");
thread.start();
object.shutdown();
Will all this object and all its methods be running on sideThread or is just the run() method of object on the side thread?
i.e. When I call shutdown() will it actually interrupt the sideThread or will it just interrupt on the main thread where the object is instantiated?
There's no additional magic in Runnable. A Thread takes a Runnable and calls its run method on a new thread. End of story. Any other methods on that object are none of Thread's business. If you want to provide tighter integration between the calling thread and the created thread, that's on you to design.
What Silvio Mayolo says is correct, any thread can call any method of an object, passing a Runnable to a thread's constructor tells the thread to execute that Runnable's run method. If you want you can pass the same object implementing Runnable to several new threads and let them all run it. No magic here.
When you call Thread.currentThread(), that returns the thread that is executing the code. So as your posted code works now, if 1) a thread A starts a new thread B passing in this Runnable, and next 2) thread A calls shutdown on the Runnable, the result is that the interrupt flag is set on thread A, not on the thread B, the one executing the run method. Probably not what you want. It would be better to keep a reference to the new thread, and call interrupt on that.
Each thread gets a name generated for it. Try adding some lines like:
System.out.println("thread=" + Thread.currentThread().getName());
in your code and it will show you which thread is executing. You will see the new thread executing the run method, and the thread that created the new thread running the shutdown method.

Using same instance of ExecutorService in different threads is thread safe?

For example, I execute runnable block via ExecutorService instance and that runnable block execute some asynchronous code via the same ExecutorService instance.
So my code looks like:
final ExecutorService eService = Executors.newFixedThreadPool(nThreads);
eService.execute(new Runnable() {
public void run() {
eService.execute(new Runnable() {
public void run() {
System.out.println("Successfully created");
}
});
}
});
Is this code thread safe, because ExecutorService doesn't have a state?
In my real app I have some threads that created new threads inside them and I want to use one ExecutorService instance(maybe a bad practice?) with configurable thread pool size.
Is it a bad practice to do have one ExecutorService instance for different threads?
And if yes, maybe there are some alternatives?
It look fine. It is a good practice to reuse threads instead of spawning new ones (which is expensive) and one of possible implementations of such thread sharing can be usage of ExecutorService
Just keep in mind, that it will work for the code you have mentioned, It might break if you will try to await for the result of scheduled operation. This can lead to obvious deadlock when all the threads (from the pool) will be waiting for the result of the operation that awaits a free thread (in that pool) to execute it.

problem using isAlive(),Interrupt() and stop() methods of a Thread inside ExecuterService

i have found that isAlive() method is not working when executing a thread using ExecuterService.
And interrupt() and stop() method is also not working.
The code i used:
Thread t1=new Thread(()->{
try{
Thread.sleep(10000);
} catch(InterruptedExeception ie){
System.out.println("Interrupted");
}
Thread.sleep(5000);
System.out.println("It's Done");
});
ExecuterService excuter=Executers.newSingleThreadExecuter();
excuter.execute(t1);
Thread.sleep(2000);
System.out.println(t1.isAlive());
Thread.sleep(2000);
t1.interrupt();
t1.stop();
My expected output is :
true
Interrupted
Actual output is :
false
It's Done
I need reason for this behavior. And I want to know what is the solution for the problem and how I use these methods when a Thread is running inside a ThreadPool.
The stop() method does not work. You can't stop threads like this. A thread needs to opt into allowing itself to be stopped; you'd for example update a (volatile, or AtomicBoolean-style) boolean, and the thread runs a loop, and on each loop, checks that boolean; if it's false, it ends. There is no way to stop arbitrary threads in their tracks. At all. You can google for information about why Thread.stop is deprecated (and effectively doesn't work at all anymore, even though the method is still around, primarily as vehicle for the documentation on why you can't do that anymore).
Threads implement runnable, which is why you're even allowed to pass that thread to the executor method, but the entire thread infra isn't being used at all. You should update this code to be Runnable r = () -> { ... } and pass that. Your code as written is misleading you into thinking that's the thread that is being run. It's not, which is why you're getting false for .isAlive().
Executors as a rule don't expose the way they do the job, they just do it. If you want to check if the job is running, set a (volatile, or AtomicBoolean) boolean to true upon entry, and to false upon exit. Alternatively, don't bother with an executor service, just start your thread, if you really want to use thread functionalities such as .isAlive().
t1 is not a thread.
t1 is a Thread instance, but a Thread instance is not the same thing as a thread, and the way you are using t1, no thread is ever created. Think of a Thread instance as a handle that you use to create and control a thread. The thread would be created if your program called t1.start(), and then the t1.isAlive() and t1.interrupt() and t1.stop() calls all would operate on that new thread.
Besides being a Thread instance, t1 also happens to be a Runnable instance, which is what the executer.execute(...) call wants. Being a Runnable just means that t1 has a run() method. There are various ways that run() method could be called:
You could start the thread, t1.start(), in which case, the new thread would call it,
You could (you did) give it to an Executor. When you do that, the Executor arranges to have one of its worker threads call your run() method.
You could simply call it -- t1.run() -- which is no different from calling any other method that your code defines.
You could pass it to any other library method that wants a Runnable. (I don't know how many there are, maybe a lot.)
If you want t1.run() to be called in a thread that your code can control, then call t1.start() to create that thread. If you want it to be called by an executor service, whose threads you should not attempt to control, then do what you did: call excuter.execute(t1);
Just don't do both. That probably isn't what you want.
P.S., If you want to continue using the Executor service, then you probably should change your declaration of t1. Since it only needs to be a Runnable in that case, you can write:
Thread t1=new Runnable(()->{
...
});
That way, people reading your code won't scratch their heads and wonder whether you knew what you were doing.

Attempt to start Thread again or make a new one? [duplicate]

This question already has answers here:
How to start/stop/restart a thread in Java?
(9 answers)
Closed 9 years ago.
What are all the different possibilities to bring the dead thread back to runnable state.
If you look at the Thread Life Cycle Image, there is no way you can go back to new position once your thread has terminated.
So there is no way to bring back the dead thread to runnable state,instead you should create a new Thread instance.
From the JavaDocs...
It is never legal to start a thread more than once. In particular, a
thread may not be restarted once it has completed execution.
You'll have to start a brand new instance.
Preferably, the actions you want to execute should be wrapped up in a Runnable interface, that way you can simply pass the Runnable to a new instance of Thread
I guess you extended the Thread class and you have overridden the run method. If you do this you are tying the runnable code to the Thread's lifecycle. Since a Thread can not be restarted you have to create a new Thread everytime. A better practice is to separate the code to run in a thread from a Thread's lifecycle by using the Runnable interface.
Just extract the run method in a class that implements Runnable. Then you can easily restart it.
For example:
public class SomeRunnable implements Runnable {
public void run(){
... your code here
}
}
SomeRunnable someRunnable = new SomeRunnable();
Thread thread = new Thread(someRunnable);
thread.start();
thread.join(); // wait for run to end
// restart the runnable
thread = new Thread(someRunnable);
thread.start();
This practice makes it also easy if you need to remember the previous run state.
public class SomeRunnable implements Runnable {
private int runs = 0;
public void run(){
runs++;
System.out.println("Run " + runs + " started");
}
}
PS: Use a java.util.concurrent.Executor to execute Runnables. This will decouple thread management from execution.
Executor executor = Executors.newSingleThreadExecutor();
...
SomeRunnable someRunnable = new SomeRunnable();
executor.execute(someRunnable);
Take a look at Executor Interfaces
The thread is a separate light weight process which executes independently irrespective of other threads. Once its execution is complete, there exists no means to restart it.
The other obvious solution is: if you need the thread functionality many times, don't let the thread die. Instead of letting it exit, and so terminate itself, shove in a while(true) loop with a suitable wait at the top. You can then make it 'restart' its work by signaling it.
This is much quicker, safer and more efficient than continually creating/terminating/destroying threads.
When the execution of run() method is over, as the job it is meant is done, it is brought to dead state. It is done implicitly by JVM. In dead state, the thread object is garbage collected. It is the end of the life cycle of thread. Once a thread is removed, it cannot be restarted again (as the thread object does not exist).
Read more From Here about life cycle of Threads.
Thread has many different state through out its life.
1 Newborn State
2 Runnable State
3 Running State
4 Blocked State
5 Dead State
Thread should be in any one state of above and it can be move from one state to another by different methods and ways.
When a thread is completed executing its run() method the life cycle of that particular thread is end.
We can kill thread by invoking stop() method for that particular thread and send it to be in Dead State.

Thread and Runnable object differences

I couldn't find a question similar enough to this, but I do apologize if this is a duplicate.
//do something
//start
new Thread(r).start();
Runnable r = new Runnable() {
public void run() {
try{
Thread.sleep(5000);
//do something
}
catch(InterruptedException e){}
}
};//end new Runnable
My question is: Am I using a thread? or just a runnable object? Not sure if I am even asking a meaningful question?
I am new to threads, but my understanding of this code is : I am starting a new thread, passing it a runnable object, and it begins the overridden run method, in this case the thread will sleep for 5 seconds then do work.
Yes, you're using a Thread.
You create it by passing to its constructor a Runnable object.
"I am starting a new thread, passing it a runnable object, and it begins the overridden run method, in this case the thread will sleep for 5 seconds then do work."
This is correct, but the key point is missing: that this run method will be executed in another/new Thread, and not in the Thread from which you called start() on the Thread object which you created.
The Runnable interface just declares the fact that the class that implements it is able to be executed in a thread, so that it provides the interface to be called and executed by an external thread, nothing more.
A Thread implements Runnable since it's able to execute its own run() method but Runnable in general doesn't have anything related to threading itself. The default run() of Thread doesn't do anything, that's why you usually extend it and define the specific behavior of your thread.
But just to clarify, a ThreadPoolExecutor accepts Runnable objects exactly like a Thread. It's just the interface which declares that the class definition, is indeed, runnable (or executable).
You created a new anonymous implementation of Runnable interface.
This implementation povided the action to perform when executing the this implementation in a new Thread
You created a new Thread (new Thread(r)) and passed the anonymous instance to thread instance
When you started executing the thread (new Thread(r).start()), the jvm created a new thread. This new thread in turn invoked the run() method of the anonymous Runnable implementation.
An instance of Thread (as you create in the first line of code) represents a physical thread. When you call start(), the JVM will spawn a new thread (using the OS native methods to do so) and start its execution.
A Runnable is just an interface that defines the run() method (as you do in your second line of code). If you pass any object implementing Runnable to the Thread constructor, then the thread will run the code defined in the run() method.
Runnables are very lightweight since they only define one method, while Threads come with the heavy weight of a physical thread.
Directly creating a Thread is not recommended since it's an expensive operation. I highly recommend you look at the java Executors framework as it provides a flexible way of creating thread pools and submitting tasks (in the form of Runnables or Callables) to them. The Executors framework provides invaluable facilities for thread reuse.

Categories

Resources