Ok, I know it's probabblly mz bad understanding of how threads really work, but until someone helps me understand I'll believe that it's a bug :)
In my Main class and its main() method I have:
public static void main(String args[]){
StoneBucket stoneBucket = new StoneBucket();
StonePutter spRunnable = new StonePutter(stoneBucket);
StoneThrower stRunnable = new StoneThrower(stoneBucket);
StoneThrower stRunnable2 = new StoneThrower(stoneBucket);
//Create the Threads that will take the Runnables as arguments
Thread puttingThread = new Thread(spRunnable);
Thread throwingThread = new Thread(stRunnable);
Thread throwingThread2 = new Thread(stRunnable);
puttingThread.setName("Putter");
throwingThread.setName("Thrower 1");
throwingThread2.setName("Thrower 2");
[...]
And then in my StoneThrower class I have
public class StoneThrower implements Runnable{
private StoneBucket sb;
private String name;
public StoneThrower(StoneBucket _sb){
this.sb = _sb;
}
public void run(){
name = Thread.currentThread().getName();
System.out.println("T::"+name+" started...");
int count = 0;
while(true){
[...]
When I compile and run this code I'm getting:
So, my question is why do both of these threads return the same name for currentThread().getName()
?
When they were created they were assigned the name through threadX.setName("XXX")
and those runnables are started by calling threadX.start()
...
Could someone please clarify me this?
EDIT: I accepted the correct answer because changing the stRunnable to stRunnable2 the behaviour is as expected. The real question is now why does this happen. I create two threads and start them separately. How is it posibble that the run() method (called once when the thread's created) returns wrong name ?
This happens because you store thread name in instance variable name
of your StoneThrower
. Because of concurrency, second thread overrides value of name
that first thread has just set and both of them output the same value.
Here is your scenario:
1. Thread1#start
2. Thread2#start
3. Thread1#runnable#run -> runnable.name = 'Thrower 1'
4. Thread2#runnable#run -> runnable.name = 'Thrower 2' // overrides
5. Thread1#runnable#run -> System.out.println(runnable.name)
6. Thread2#runnable#run -> System.out.println(runnable.name)
You create both threads with the same runnable:
Thread throwingThread = new Thread(stRunnable);
Thread throwingThread2 = new Thread(stRunnable);
^^^^^^^^^^ stRunnable2?
You store the thread name in an instance variable of the Runnable
object. Since the object is shared by the two threads, the second thread to execute name = Thread.currentThread().getName()
overwrites the first thread's name with its own.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With