Goldman Sachs Interview Question
Java DevelopersCountry: India
Interview Type: In-Person
If T1 and T2 are different Threads not on same object working on their own critical sections they both interfere.In the above problem he didnt mentioned that both the threads are on same object.he has created an object to access critical secction part,
but threads may be different
public class ThreadTest {
public static void main(String[] args) {
A a1 = new A();
A a2 = new A();
new Thread(new MyRunnable1(a1), "T1").start();
new Thread(new MyRunnable2(a1), "T2").start();
}
static class MyRunnable1 implements Runnable {
A a;
public MyRunnable1(A a) {
super();
this.a = a;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
a.m1();
}
}
}
static class MyRunnable2 implements Runnable {
A a;
public MyRunnable2(A a) {
super();
this.a = a;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
a.m2();
}
}
}
static class A {
public synchronized void m1() {
System.out
.println(Thread.currentThread().getName() + " running");
}
public synchronized void m2() {
System.out
.println(Thread.currentThread().getName() + " running");
}
}
}
If both Threads(T1 , T2) would have been created on different objects (a1 , a2) then both threads would have executed m1() and m2() simultaneously.
output will be like:-
T1 Running
T2 Running
sometime
T2 Running
T1 Running
If both Threads (T1 , T2) would have been created on same objects (a1) then both threads would have executed m1() and m2() simultaneously.
output will be like:-
T1 Running
T2 Running
T1 Running
T2 Running
........
Here there are two scenario:
1) if both the threads are created on the same object , Then if one thread enters into m1 and the other thread cannot enter into m2 as in java the lock is on the object and java supports two synchronization methods the mutex and co-operative .Mutex is achieved by the synchronized keyword and co-operative is achieved by the , notify , notifyAll , wait etc .Once the lock is acquired on that object no other thread can enter the monitor , they will be in wait sate , and once the object lock is released when T1 comes out of the monitor then the thread shceduler gets notified and again contention for that monitor starts .
2) If both the threads are creatd on different objects then there is no issue , T1 will enter M1 and T2 will enter M2 as the lock for two different objects are different.
I think you are confused synchronization is defined on method level so why thread will acquire object level lock even though objects are same.
Both thread will run and will be able to access both methods
public class TestThread {
public static void main(String[] args) {
B a = new B();
new Thread(new MyThread(a), "T1").start();
new Thread(new MyThread(a), "T2").start();
}
public static class MyThread implements Runnable {
B b;
public MyThread(B a) {
this.b = a;
}
@Override
public void run() {
while (true) {
if ("T1".equals(Thread.currentThread().getName())) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
b.method1();
} else {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
b.method2();
}
}
}
}
public static class B {
synchronized public void method1() {
System.out.println("Inside method1");
}
synchronized public void method2() {
System.out.println("Inside method2");
}
}
}
public class Thread1 {
public static void main(String[] args) {
A a = new A();
new Thread(new MyRunnable(a), "T1").start();
new Thread(new MyRunnable(a), "T2").start();
}
static class MyRunnable implements Runnable {
A a;
public MyRunnable(A a) {
super();
this.a = a;
}
@Override
public void run() {
while (true) {
if ("T1".equals(Thread.currentThread().getName())) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
a.m1();
} else {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
a.m2();
}
}
}
}
}
static class A {
public synchronized void m1() {
System.out
.println(Thread.currentThread().getName() + " running");
}
public synchronized void m2() {
System.out
.println(Thread.currentThread().getName() + " running");
}
}
}
For the above code , its only printing
T1 Running
T1 Running
T1 Running
T1 Running
T1 Running
....
So T1 thread is taking the lock every time .
If both the threads are created on the same object(which is the case in above), then only one of the thread would be able to enter any synchronized methods in that class. Reason being that non-static synchronized methods obtain lock on Object ,and thus say if T1 enters m1() it means it has acquired lock on Object a1 and now if T2 tries to enter m2() it would fail to obtain the lock on a1 and thus would go in wait state.
- Algorithmist July 11, 2013Note:If both Threads would have been created on different objects then both threads would have executed m1() and m2() simultaneously.