Thread getName() returns wrong name - java

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.

Related

Synchronisation block does not work correctly

I'm trying to run the below code but can't get the correct output.
Expected Output
"welcome new programmer"
Actual output
"new welcome programmer"
class First {
public synchronized void display(String msg) {
System.out.print("["+msg);
System.out.println("]");
}
}
class Second {
String msg;
First fobj;
Second (First fp,String str) {
fobj = fp;
msg = str;
start();
}
public void run() {
synchronized(fobj) { //Synchronized block
fobj.display(msg);
}
}
}
public class SyncroBlock {
public static void main (String[] args) {
First fnew = new First();
Second ss = new Second(fnew, "welcome");
Second ss1 = new Second(fnew,"new");
Second ss2 = new Second(fnew, "programmer");
}
}
Where I did wrong here?
Can anyone correct me please?
Starting a thread from a constructor is a bad idea. It violates the principles of safe construction.
A common mistake that can let the this reference escape during construction is to start a thread from a constructor. When an object creates a thread from its constructor, it almost always shares its this reference with the new thread, either explicitly (by passing it to the constructor) or implicitly (because the Thread or Runnable is an inner class of the owning object). The new thread might then be able to see the owning object before it is fully constructed.
There’s nothing wrong with creating a thread in a constructor, but it is best not to start the thread immediately. Instead, expose a start or initialize method that starts the owned thread. Calling an overrideable instance method (one that is neither private nor final) from the constructor can also allow the this reference to escape.
3.2.1 Safe construction practices, Java Concurrency in Practice by Brian Goetz
Thread#start() call might take some time, so the expected "welcome -> "new" -> "programmer" actually can be in any order.
To do what you were planning, we need to make sure that the previous run() has started executing before you go to the next one. For my machine, a sleep for 100L between the calls was enough to get the right order.
Second ss = new Second(fnew, "welcome");
Thread.sleep(100L);
Second ss1 = new Second(fnew,"new");
Thread.sleep(100L);
Second ss2 = new Second(fnew, "programmer");
That isn't a good technique, you shouldn't utilise it like this. It makes execution sequential - we won't derive any benefits from multithreading.
I think you forget to implement Callable or Runnable or whatever you need for your Second class.

Output result is different while passing argument to thread methods

So I am trying to pass arguments to my threads and my output is not as expected. Below is my code:
class BadThreadParam implements Runnable {
static int c;
public BadThreadParam( int a, int b ) {
c = a + b;
}
public void run() {
System.out.println( c );
}
}
public class BadThreadParamTest {
public static void main( String[] args ) {
BadThreadParam shouldBe3 = new BadThreadParam( 1, 2 );
BadThreadParam shouldBe5 = new BadThreadParam( 3, 12 );
shouldBe3.run(); // Expect 3 but is 15. WTF?
shouldBe5.run(); // Expect 15.
}
}
The final output I am expecting is:
3
15
but I am getting:
15
15
So is this a problem of thread interference? Can anyone explain why this is happening?
What if you change
static int c;
to
private int c;
Since you don't access the variable c out of your class, there is no reason it should be static. If you make it static, each time you change it, it will be that last value.
If you change it to private it's an 'instance' variable that is linked to the instance you create with new BadThreadParam(); so the output is the value that is given to that specific instance.
c is a static variable. This means that when one thread changes it, it changes for everyone.
You probably intend for it to be an instance variable.
I just re-ordered the lines in your main method and here is the difference
public static void main(String[] args) {
BadThreadParam shouldBe3 = new BadThreadParam(1, 2);
shouldBe3.run();
BadThreadParam shouldBe5 = new BadThreadParam(3, 12);
shouldBe5.run();
}
And here is the output
3
15
Have a look at this along with the answers posted by #JC97 & #Joe C
Hope this will clear your doubts about the static variables
You asked if the problem you're seeing is caused by thread interference. There is no possibility for thread interference in the posted program, because there's only one thread.
You're calling run on a Runnable, which executes it in the current thread.
If you want to create a new thread to execute each of your Runnables then you should change the code to
new Thread(shouldBe3).start();
new Thread(shouldBe15).start();
and then you will have a program with multiple threads. At that point there will be no guarantee that one thread will print its output before the other.
To confirm this you can add the line
System.out.println(Thread.currentThread().getName());
to the body of each run method and to the main method. If they all print the same name then you aren't creating any threads.
As the other answers say, you're letting the second constructor call overwrite the contents of c set by the first constructor call. The static keyword means the variable belongs to the class, not to any one instance, and all instances access the same variable. c should be an instance variable (delete the static keyword) so that each Runnable object has its own copy.

Java lambdas LinkedBlockingQueue unexpected behaviour

I am trying to add elements in t linkedBlockingQueue from a thread, created using lambda, When I poll the queue using the take method, I can see that the last values entered from the thread overrides the previous values.
Following is the code :-
public List<EntryBarricade> entryBarricades() {
List<EntryBarricade> entryBarricades = new ArrayList<>();
EntryBarricade entryBarricade;
Runnable runnable;
for (int i =0;i<=1;i++) {
EntryRequest entryRequest = new EntryRequest("Barricade-"+i);
runnable = new Runnable() {
#Override
public void run() {
ExecutorService entryGate1 = Executors.newSingleThreadExecutor();
for (int j =0;j<=1;j++) {
entryGate1.submit(() -> {
entryRequest.setVehicleId(Thread.currentThread().getName()
+ " " + new Double(Math.random()));
entryRequestQueuingService.Queue(entryRequest);
});
}
}
};
entryBarricade = new EntryBarricade("Barricade-"+i, runnable);
entryBarricades.add(entryBarricade);
}
return entryBarricades;
}
After polling the queue, I get the following:-
Request{barricadeId='Barricade-0', vehicleId='pool-2-thread-1 0.9091480024731418'}
Request{barricadeId='Barricade-0', vehicleId='pool-2-thread-1 0.05687657229049259'}
Request{barricadeId='Barricade-1', vehicleId='pool-3-thread-1 0.7978996055410615'}
Request{barricadeId='Barricade-1', vehicleId='pool-3-thread-1 0.2734508504023724'}
Request{barricadeId='Barricade-0', vehicleId='pool-2-thread-1 0.05687657229049259'}
Request{barricadeId='Barricade-0', vehicleId='pool-2-thread-1 0.05687657229049259'}
Request{barricadeId='Barricade-1', vehicleId='pool-3-thread-1 0.2734508504023724'}
Request{barricadeId='Barricade-1', vehicleId='pool-3-thread-1 0.2734508504023724'}
I am not sure what is happening.
Can some one please explain this behaviour ??
Thanks,
Amar
I assume the problem here: your entryRequest is created in each iteration of your loop (in the main thread). So when the thread pool executor comes to call your lamdba it might have changed already. You have absolute no control who access when this variable.
Instead of constructing an anonymous Runnable class better write your own implementation of Runnable, pass the entryRequest as parameter to it (e.g by constructor or setter) and let the run method then operate on this passed variable. This ensures that each thread operates on its own entryRequest instance.

Creating and naming multiple, simultaneous threads with a for loop

Is there a way to create multiple threads that run simultaneously with a for loop? Consider this example:
for(int i = 1; i<=36; i++) {
if(new Random().nextInt(2)==0){
ActionThread nr = new ActionThread();
}
}
I don't want the threads to be killed after completion of the if statement. The end of each thread is randomly determined in the ActionThread class itself. Also, how do I name the threads automatically? For example, instead of nr, the first thread should be named nr1, the second nr2, the third nr3, and so on.
I'm assuming that ActionThread is some custom class that you have created that extends Thread.
I don't want the threads to be killed after completion of the if statement.
They won't be. However, it doesn't look like you have started them yet. Read the javadocs for Thread. Read the material at the top, then look at the start() and run() methods.
If you don't start a thread ... nothing happens.
Also, if you want some other part of your application to be able to "do things" to the threads once they have been created, you should replace the nr local variable with a data structure that the the rest of the application can get at; e.g. a list or an array.
(It is also possible to find extant threads via the ThreadGroup tree, but it is complicated.)
Also, how do I name the threads automatically?
Call Thread.setName(), or pass the thread name to the (relevant) Thread constructor. For example:
nr.setName("thr" + i);
Or you could even make your ActionThread set its own name in the constructor.
I should also point out that is is generally considered to be a bad idea to create subclasses of Thread. It is better to put your thread logic into a custom Runnable class, then create and pass a Runnable instance as a Thread construct argument. Like this:
public class MyRunnable implements Runnable {
#Override
public void run() {
// thread logic goes here
}
}
Thread th = new Thread(new MyRunnable());
th.start();
If you want to pass parameters to the thread logic, add a constructor to your runnable class with some arguments, and provide them when you instantiate the runnable.
Why do it this way? Because it allows you to easily change your code to use a thread loop or executor or some such.
public static void main(String[] a) {
List<ActionThread> threads = new ArrayList<>();
for (int i = 1; i <= 36; i++) {
if (new Random().nextInt(2) == 0) { // no idea why you have put this
// but seems unecessary
ActionThread thread = new ActionThread();
threads.add(thread);
thread.start();
}
}
}
class ActionThread extends Thread {
#Override
public void run() {
// Write what to do in Thread here
}
}
Once the list of ActionThread is there you have handle to all the Threads that you have created. using threads.get(index). From question its appears that by name you meant handle to Thread instance
For automatic naming, may be use static field (counter) in ActionThread and increment him in the constructor, before generate thread name.
class ActionThread extend Thread {
private static int id = 0;
ActionThread() {
setName(String.format("n%d", ++id);
}
}

Java Threads yield method query

I am practising threads, I used yield(), iam expecting output as below: (BUT not getting as expected)
One1
Two1
One2
Two2
One3
Two3
.
.
.
.
Whats wrong in my below code?
public class Main2 {
public static void main(String[] args) {
MyThread myThread1 = new MyThread("One");
MyThread myThread2 = new MyThread("Two");
/*Thread t1 = new Thread(myThread1);
Thread t2 = new Thread(myThread2);
t1.start();
t2.start();*/
myThread1.start();
myThread2.start();
}
}
class MyThread extends Thread {
private String name;
public MyThread(String name) {
this.name = name;
}
public void run(){
for(int i=1;i<=20;i++) {
System.out.println(name+i);
yield();
}
}
}
and also I would like to know does commented statements correct to use or not? I mean below:
Thread t1 = new Thread(myThread1);
Thread t2 = new Thread(myThread2);
t1.start();
t2.start();
Waiting for your replies..
The yield() method clearly states in its javadoc that it is
A hint to the scheduler that the current thread is willing to yield
its current use of a processor. The scheduler is free to ignore this
hint.
As such, you can't always expect execution to pass to another thread. There is no guarantee.
Also, in your question does commented statements correct to use or not, no, it won't change anything. The Thread constructor accepts a Runnable argument on which it will eventually execute the run() method. The Thread class implements Runnable and is therefore a valid argument, but it has the same effect as if you had started the Thread itself.
If you extend thread, you do it the way you have. If you implements Runnable, you do it the commented way. Either way is fine.
Note that yield is really just a recommendation, so the order of your output is not determined. You need to use locks or another technique if you want it to always be that certain way.
Thread#yield states that
Causes the currently executing thread object to temporarily pause and allow other threads to execute.
So you won't get expected output here.
If you want expected output use wait() and notify() methods with proper synchronization.
I would like to know does commented statements correct to use or not?
Yes this is 100% valid java syntax.

Categories

Resources