一 同一类的方法都用 synchronized 修饰
1 代码
package concurrent;
import java.util.concurrent.TimeUnit;
public class ThisMonitor {
public synchronized void method1() {
System.out.println(Thread.currentThread().getName() + " enter to method1");
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " exit to method1");
}
public synchronized void method2() {
System.out.println(Thread.currentThread().getName() + " enter to method2");
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " exit to method2");
}
public static void main(String[] args) {
ThisMonitor thisMonitor = new ThisMonitor();
new Thread(thisMonitor::method1, "T1").start();
new Thread(thisMonitor::method2, "T2").start();
}
}
2 测试
T1 enter to method1
T1 exit to method1
T2 enter to method2
T2 exit to method2
二 同一类的方法分别用 synchronized 修饰和 synchronized 代码块修饰
1 代码
package concurrent;
import java.util.concurrent.TimeUnit;
public class ThisMonitor1 {
public synchronized void method1() {
System.out.println(Thread.currentThread().getName() + " enter to method1");
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " exit to method1");
}
public void method2() {
synchronized (this) {
System.out.println(Thread.currentThread().getName() + " enter to method2");
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " exit to method2");
}
}
public static void main(String[] args) {
ThisMonitor1 thisMonitor = new ThisMonitor1();
new Thread(thisMonitor::method1, "T1").start();
new Thread(thisMonitor::method2, "T2").start();
}
}
2 测试
T1 enter to method1
T1 exit to method1
T2 enter to method2
T2 exit to method2
三 结论
上面两组代码执行的效果是一样的,使用 synchronized 关键字同步类的不同实例方法,争抢的是同一个 monitor 的 lock,而与之关联的引用则是 ThisMonitor 实例的引用。