目录
有a、b两个线程,我们基于如下代码进行改造:
- public static void main(String[] args) {
- Phone phoneA = new Phone();
- new Thread(() -> {
- phoneA.sendEmail();
- }, "a").start();
-
- try {
- TimeUnit.MICROSECONDS.sleep(200);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- new Thread(() ->
- {
- phoneA.sendSMS();
- }, "b").start();
- }
- }
-
- class Phone {
- public synchronized void sendEmail() {
- System.out.println("sendEmail");
- }
-
- public synchronized void sendSMS() {
- System.out.println("sendSMS");
- }
- }
请依次判断下在如下8个案例下,是先打印“sendEmail”?还是先打印“sendSMS”?
2个方法都是普通同步方法,方法内无其他逻辑(如下图)

结果:先打印“sendEmail”,再打印“sendSMS”
打印“sendEmail”的方法中,添加暂停3秒的

结果:(延迟3秒后)先打印“sendEmail”,再打印“sendSMS”
添加1个普通方法(无synchronized)

结果:先打印“hello”,(延迟3秒后)再打印“sendEmail”
有2个phone(两个线程使用不同的phone对象)

结果:先打印“sendSMS”,(延迟3秒后)再打印“sendEmail”
2个方法都是静态同步方法,只有一个phone(两个线程使用同一个phone对象)

结果:(延迟3秒后)先打印“sendEmail”,再打印“sendSMS”
2个方法都是静态同步方法,有2个phone(两个线程使用不同的phone对象)

结果:(延迟3秒后)先打印“sendEmail”,再打印“sendSMS”
1个方法是静态同步方法,1个方法是普通同步方法,有1个phone(两个线程使用同一个phone对象)

结果:先打印“sendSMS”,(延迟3秒后)再打印“sendEmail”
1个方法是静态同步方法,1个方法是普通同步方法,有2个phone(两个线程使用不同的phone对象)

结果:先打印“sendSMS”,(延迟3秒后)再打印“sendEmail”
当对方法加synchronized关键字时,锁的是当前对象(this),所以即使是多线程只要调用的是同一个对象的synchronized方法,就需要串行执行(案例1和案例2),未被synchronized修饰的普通方法则不受影响(案例3)
如果是不同对象则不受影响(案例4),分别在自己的对象上加锁,不会影响到别的对象
当在带有“static”的方法上加了synchronized关键字时,锁的是当前类,无论几个对象,都要抢类的这一把锁,因而是否使用同一对象都会串行执行
对于同步代码块呢,锁的是sychronized括号的对象