Output result is different while passing argument to thread methods - java

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.

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.

can multiple threads with different objects of same runnable class overlap

Does creating a new object everytime of runnable class and passing it to Thread create multithreading problems.
For example:
class exmpl implements Runnable {
int a = 0;
exmpl(int x) {
a = x;
}
}
public class toRun {
public static void main(String[] args) {
Thread t = new Thread(new exmpl(5));
Thread t1 = new Thread(new exmpl(6));
t.start();
t1.start();
}
}
Will the two thread overlap ? ie. will the value of a for t be 5 and for t1 be 6 always?
The value of a in the exmpl instance that you construct for the t thread is initially set to 5, and the value of a in the other exmpl instance is initially set to 6, but a is not a final variable, and you have not shown us the run() method. Whether or not the two a fields will ever change depends on what the run() method does with them.
Both t and t1 are totally different objects, the value of a in each instance will be kept unless you modified it.
Yes, of course! The whole point of threads is that is so that multiple threads (even if they're different objects of class thread will run at once.
Think about it:
If it were impossible to run multiple threads at once, then wouldn't you just use individual methods? That way, the code would run in a single order, going from 1 to 2 to 3.
The thing is, java has something called a thread. The whole point of this thread is so that instead of going from 1 to 2 to 3, the compiler can execute 1 2 and 3 all at the same time.

Multi-threading program to print numbers from 1 to 50?

im trying to write a program in which two threads are created and the output should be like 1st thread prints 1 and the next thread prints 2 ,1st thread again prints 3 and so on. im a beginner so pls help me clearly. i thought thread share the same memory so they will share the i variable and print accordingly. but in output i get like thread1: 1, thread2 : 1, thread1: 2, thread2 : 2 nd so on. pls help. here is my code
class me extends Thread
{
public int name,i;
public void run()
{
for(i=1;i<=50;i++)
{
System.out.println("Thread" + name + " : " + i);
try
{
sleep(1000);
}
catch(Exception e)
{
System.out.println("some problem");
}
}
}
}
public class he
{
public static void main(String[] args)
{
me a=new me();
me b=new me();
a.name=1;
b.name=2;
a.start();
b.start();
}
}
First off you should read this http://www.oracle.com/technetwork/java/codeconventions-135099.html.
Secondly the class member variables are not shared memory. You need to explicitly pass an object (such as the counter) to both objects, such that it becomes shared. However, this will still not be enough. The shared memory can be cached by the threads so you will have race-conditions. To solve this you will need to use a Lock or use an AtomicInteger
It seems what you want to do is:
Write all numbers from 1 to 50 to System.out
without any number being printed multiple times
with the numbers being printed in order
Have this execution be done by two concurrent threads
First, let's look at what is happening in your code: Each number is printed twice. The reason for this is that i is an instance variable of me, your Thread. So each Thread has its own i, i.e., they do not share the value.
To make the two threads share the same value, we need to pass the same value when constructing me. Now, doing so with the primitive int won't help us much, because by passing an int we are not passing a reference, hence the two threads will still work on independent memory locations.
Let us define a new class, Value which holds the integer for us: (Edit: The same could also be achieved by passing an array int[], which also holds the reference to the memory location of its content)
class Value{
int i = 1;
}
Now, main can instantiate one object of type Value and pass the reference to it to both threads. This way, they can access the same memory location.
class Me extends Thread {
final Value v;
public Me(Value v){
this.v = v;
}
public void run(){
for(; v.i < 50; v.i++){
// ...
}
public static void main(){
Value valueInstance = new Value();
Me a = new Me(valueInstance);
Me b = new Me(valueInstance);
}
}
Now i isn't printed twice each time. However, you'll notice that the behavior is still not as desired. This is because the operations are interleaved: a may read i, let's say, the value is 5. Next, b increments the value of i, and stores the new value. i is now 6. However, a did still read the old value, 5, and will print 5 again, even though b just printed 5.
To solve this, we must lock the instance v, i.e., the object of type Value. Java provides the keyword synchronized, which will hold a lock during the execution of all code inside the synchronized block. However, if you simply put synchronize in your method, you still won't get what you desire. Assuming you write:
public void run(){ synchronized(v) {
for(; v.i < 50; v.i++) {
// ...
}}
Your first thread will acquire the lock, but never release it until the entire loop has been executed (which is when i has the value 50). Hence, you must release the lock somehow when it is safe to do so. Well... the only code in your run method that does not depend on i (and hence does not need to be locking) is sleep, which luckily also is where the thread spends the most time in.
Since everything is in the loop body, a simple synchronized block won't do. We can use Semaphore to acquire a lock. So, we create a Semaphore instance in the main method, and, similar to v, pass it to both threads. We can then acquire and release the lock on the Semaphore to let both threads have the chance to get the resource, while guaranteeing safety.
Here's the code that will do the trick:
public class Me extends Thread {
public int name;
final Value v;
final Semaphore lock;
public Me(Value v, Semaphore lock) {
this.v = v;
this.lock = lock;
}
public void run() {
try {
lock.acquire();
while (v.i <= 50) {
System.out.println("Thread" + name + " : " + v.i);
v.i++;
lock.release();
sleep(100);
lock.acquire();
}
lock.release();
} catch (Exception e) {
System.out.println("some problem");
}
}
public static void main(String[] args) {
Value v = new Value();
Semaphore lock = new Semaphore(1);
Me a = new Me(v, lock);
Me b = new Me(v, lock);
a.name = 1;
b.name = 2;
a.start();
b.start();
}
static class Value {
int i = 1;
}
}
Note: Since we are acquiring the lock at the end of the loop, we must also release it after the loop, or the resource will never be freed. Also, I changed the for-loop to a while loop, because we need to update i before releasing the lock for the first time, or the other thread can again read the same value.
Check the below link for the solution. Using multiple threads we can print the numbers in ascending order
http://cooltekhie.blogspot.in/2017/06/#987628206008590221

Threads - why exception is thrown at runtime?

I am confused at the output of the following program
public class ChicksYack implements Runnable {
Chicks c ;
public static void main(String[] args){
new ChicksYack().go();
}
void go(){
c= new Chicks();
new Thread(new ChicksYack()).start();
new Thread(new ChicksYack()).start();
}
public void run() {
c.yack(Thread.currentThread().getId());
}
}
class Chicks{
synchronized void yack(long id){
for(int x = 1 ; x < 3 ; x++){
System.out.print(id + " ");
Thread.yield();
}
}
}
The program throws NullPointerException at run-time. Will the value of Chicks variable c won't be shared on thread-1 and thread-2 stack. I know i am making a pretty silly mistake but pretty confused. Any pointers will be helpful.
If you're ensuring that there is an instance of Chicks in each instance of ChicksYack, then you need to move the line:
c= new Chicks();
into a constructor e.g.
public ChicksYack() {
c= new Chicks();
}
and change the type of the member variable from Chicks c to final Chicks c; otherwise you are not guaranteed that you will see it fully constructed in the threads. Adding the final keywoard ensures that:
When the constructor exits, the values of final fields are guaranteed to be visible to other threads accessing the constructed object. (ref: Javamex.com website)
As is, you're creating two more instances of ChicksYack that don't have the c member initialized.
Now if you're intending on having only a single instance of Chicks shared amongst all the instances of ChicksYack, then you need to declare it as static e.g.
static Chicks c;
you have three instances of ChicksYack and not-static field for Chicks.
I think you should change go method to something like this
void go(){
c= new Chicks();
new Thread(this).start();
new Thread(this).start();
}
The program throws NullPointerException at run-time. Will the value of Chicks variable c won't be shared on thread-1 and thread-2 stack.
Nothing in a computer really happen immediately. If you believed anything was instant, forget that. This means that while a thread can update a field, it takes time to be visible to other threads.
There is a number of exceptions, one is using volatile fields (It is still not instant instead it waits for any update) and the other is any field set before a thread is started. If this program really throws an NPE for you I would suspect you have a bug in your JVM. I would make sure you have the latest version

Thread getName() returns wrong name

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.

Categories

Resources