Reputation: 384
I have a very simple code but unable to understand.
public class Test extends Thread {
public synchronized void testPrint() {
System.out.println("I am sleeping..."
+ Thread.currentThread().getName());
try {
Thread.sleep(3000);
System.out.println("I am done sleeping..."
+ Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
Test t = new Test();
t.testPrint();
System.out.println("I am out..." + Thread.currentThread().getName());
}
public static void main(String[] args) {
Test t1 = new Test();
Test t2 = new Test();
t1.start();
t2.start();
}
}
Here is my questions
Test t = new Test()
, does this create two different objects with same name? What happens at this line with multiple threads?I am getting below result,
I am sleeping...Thread-0
I am sleeping...Thread-1
I am done sleeping...Thread-0
I am out...Thread-0
I am done sleeping...Thread-1
I am out...Thread-1
From the output, It definitely means that there are two objects created, that is why both the threads could enter in the sync method. hope my understanding is correct ? How system maintains these two objects?
Upvotes: 0
Views: 7985
Reputation: 6203
With your current approach, you ensure that for each instance of Test
the method testPrint()
can not run concurrently. It all depends on what you want to do. I assume that you want to protect the testPrint()
method from running in multiple threads concurrently, with multiple instances of Test
.
Currently you use the synchronized
keyword directly on the method. This results in using the object itself (an instance of Test
) being used for synchronization.
You should synchronize on another object that is shared between the instances of Test
(you could for example make the lock object static).
Also note, that it is general a better idea to implement only the Runnable
interface and then pass the implementation to the thread.
Plus, you don't have to create a new instance of Test
every time you run (i don't see the purpose of that), i commented that out.
public class Test extends Thread {
// could also use a static monitor instead.
// private static final Object monitor = new Object();
private final Object monitor;
public Test(final Object monitor) {
this.monitor = monitor;
}
public void testPrint() {
synchronized (monitor) {
System.out.println("I am sleeping..." + Thread.currentThread().getName());
try {
Thread.sleep(3000);
System.out.println("I am done sleeping..." + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void run() {
//Test t = new Test(monitor);
//t.testPrint();
testPrint();
System.out.println("I am out..." + Thread.currentThread().getName());
}
public static void main(String[] args) {
// synchronization will happen on this object.
final Object monitor = new Object();
Test t1 = new Test(monitor);
Test t2 = new Test(monitor);
t1.start();
t2.start();
}
}
Upvotes: 2
Reputation: 14278
Test t = new Test()
This will create a object in the heap and the reference will be placed in the stack.
Here in your example you dont need the synchronized
method at all because you are not sharing the instance among different thread.
Upvotes: 0
Reputation: 69025
You are creating two different object which will have two different monitors on which lock will be acquired. As both thread work on different objects synchronization does not come into picture.
You can try
public class Test extends Thread {
Object obj;
public Test(Object obj){
this.obj = obj;
}
public synchronized void testPrint() {
System.out.println("I am sleeping..."
+ Thread.currentThread().getName());
try {
Thread.sleep(3000);
System.out.println("I am done sleeping..."
+ Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
((Test)obj).testPrint();
System.out.println("I am out..." + Thread.currentThread().getName());
}
public static void main(String[] args) {
Object obj = new Test(null);
Test t1 = new Test(obj);
Test t2 = new Test(obj);
t1.start();
t2.start();
}
}
and the output is
I am sleeping...Thread-1
I am done sleeping...Thread-1
I am out...Thread-1
I am sleeping...Thread-2
I am done sleeping...Thread-2
I am out...Thread-2
as expected.
Upvotes: 2
Reputation: 870
When you run Test t = new Test()
jvm create new object on heap and put variable t with link to that object on stack of current thread.
When you run that code in two or more different threads each of them have own stack, so each of them create his own variable t and object Test
Upvotes: 1