看一道关于synchronized的面试题:
问题:m2()方法的执行 需要 等待m1()方法执行结束吗?
如果m2()方法上也有synchronized修饰呢,同样的问题,需要等吗?
题目代码:
public class Test02 {
public static void main(String[] args) {
MyClass mc = new MyClass();
MyThread t1 = new MyThread(mc);
MyThread t2 = new MyThread(mc);
t1.setName("t1");
t2.setName("t2");
t1.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
}
class MyThread extends Thread {
MyClass mc;
public MyThread(MyClass mc) {
this.mc = mc;
}
@Override
public void run() {
if (Thread.currentThread().getName().equals("t1")) {
mc.m1();
}
if (Thread.currentThread().getName().equals("t2")) {
mc.m2();
}
}
}
class MyClass {
public synchronized void m1() {
System.out.println("m1 begin");
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("m1 over");
}
public void m2() {
System.out.println("m2 begin");
System.out.println("m2 over");
}
}
问题一:不需要。
因为synchronized出现在实例方法上,锁的确实是this对象。
当多个线程共同访问这个对象的m1()方法时,需要排队执行。
但m2()方法上没有synchronized修饰,表示这个方法不需要找锁也能共同执行。
问题二:需要。
因为synchronized出现在m1()和m2()方法上,它们的锁是一样的,都是锁的this对象。
如果t1在访问m1(),表示t1已经拿走了this对象的这把锁,此时也需要这把锁的方法无法被别的线程执行。
m1()和m2()都需要this对象这把锁打开才能执行,而m1()方法先执行, 锁已经上锁了,m2()也跟着上锁了,只有m1()方法执行完,锁打开时,m2()方法才能被执行。
继续修改代码,问同样的问题。
public class Test03 {
public static void main(String[] args) {
MyClass mc1 = new MyClass();
MyClass mc2 = new MyClass();
MyThread t1 = new MyThread(mc1);
MyThread t2 = new MyThread(mc2);
t1.setName("t1");
t2.setName("t2");
t1.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
}
同样的问题:m1()和m2()都使用了synchronized修饰:
m2()方法的执行 需要 等待m1()方法执行结束吗?
不需要,因为2个对象2把锁,不影响相互执行。
如果m1和m2方法都继续加static修饰呢,需要等待吗?
需要,static synchronized表示锁是类锁,所有对象共用这把锁,需要等待。