我接受了采访,我被问到一个有两个函数m1()和m2()的类。 m1()是同步的,而m2()不是,并且两个线程t1和t2正在尝试访问此对象。现在如果t1正在访问m1()函数,那么t2可以同时访问m2()方法吗?
我说是应该允许它访问它,因为m2()方法没有锁定,但是访问者坚持认为,因为锁定在同一个对象上,所以不允许访问m2()函数为t2线程。
为此,我写了一个检查程序,发现无论我说的是对的。请查看带有输出的程序。
class myExperiment2 implements Runnable{
myThreadEx m;
myExperiment2(myThreadEx m){
this.m = m;
}
@Override
public void run() {
try {
m.m2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class myExperiment1 implements Runnable{
myThreadEx m;
myExperiment1(myThreadEx m){
this.m = m;
}
@Override
public void run() {
try {
m.m1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class myThreadEx{
synchronized void m1() throws InterruptedException {
System.out.println("1 am in m1....1");
Thread.sleep(10000);
System.out.println("I am in m1()");
Thread.sleep(10000);
System.out.println("1 am in m1....2");
}
void m2() throws InterruptedException{
System.out.println("1 am in m2....1");
Thread.sleep(5000);
System.out.println("i am in m2()");
Thread.sleep(5000);
System.out.println("1 am in m2....2");
}
}
public class ThreadEx {
public static void main(String args[]){
myThreadEx m = new myThreadEx();
Thread t1 = new Thread(new myExperiment1(m));
Thread t2 = new Thread(new myExperiment2(m));
t1.start();
t2.start();
}
}
输出
上午1点在m1 .... 1 凌晨1点在m2 .... 1
我在m2()
凌晨1点在m2 .... 2
我在m1()
凌晨1点在m1 .... 2
如果我遗失某些东西,或者有可能出现我可能出错的情况,无论采访是什么,有人可以建议我,是吗?
答案 0 :(得分:3)
除非我误解了这个问题,否则你没有准确地联系到这个问题,面试官就错了。
当然,给定the semantics of synchronized methods:
synchronized void foo() { ... }
与
相同void foo() { synchronized (this) { ... } }
(至少对于一个实例方法)
然后其他线程总是可以同时“访问”该方法(例如,多个线程在其堆栈跟踪中具有该方法);他们马上被阻止了。
答案 1 :(得分:1)
我会说面试官错了。如果m1
和m2
同步,他就会是对的。在你的问题的情况下,没有与m2
相关联的锁,因此没有什么能阻止其他线程执行它。
答案 2 :(得分:0)
面试官错了,除非他的意思如下,
您可以采用两种类型锁定策略
this
,如您的情况或HashTable)私人锁,
public class PrivateLock {
private final Object myLock = new Object();
@GuardedBy("myLock") Widget widget;
void someMethod() {
synchronized(myLock) {
// Access or modify the state of widget
}
}
}
所以,如果某人正在做以下操作会导致m2无法调用,
//myThreadEx also shared by another class which does myThreadEx.m1
synchronized(myThreadEx) {
myThreadEx.m2();
}