juc之8锁问题

8锁问题

问题:Phone 有两个方法,发送邮件和发送短信,每个方法都打印一句话,现在通过不同的方式对方法进行操作,回答出打印的先后顺序

1、标准访问,两线程中间睡眠 2 毫秒,先打印邮件还是短信?

class Phone {
    public synchronized void sendEmail() {
        System.out.println("send email...");
    }

    public synchronized void sendSMS() {
        System.out.println("send SMS...");
    }
}

public class Lock8 {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        new Thread(() -> phone.sendEmail(), "A").start();
        TimeUnit.MILLISECONDS.sleep(200);
        new Thread(() -> phone.sendSMS(), "A").start();

    }
}

答案:
send email…
send SMS…

分析:main线程创建A线程后,睡眠200ms,此时,A线程进入就绪状态,而B线程还没有创建,200ms已经足够A线程获取cpu的时间片。

2、在 sendEmail() 方法中睡眠 4 秒,先打印邮件还是短信?

class Phone {
    public synchronized void sendEmail() throws Exception {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("send email...");
    }

    public synchronized void sendSMS() {
        System.out.println("send SMS...");
    }
}

public class Lock8 {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        new Thread(() -> {
            try {
                phone.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "A").start();
        TimeUnit.MILLISECONDS.sleep(200);
        new Thread(() -> phone.sendSMS(), "A").start();

    }
}

答案:
send email…
send SMS…

分析:一个对象内如果有多个synchronized 方法,同一时间点,只会有一个线程去调用synchronized 方法,synchronized 锁的是当前对象this,被锁定后,其他线程都不能进入到当前对象的其他synchronized 方法,所以A线程一定比B线程先执行,而sleep()方法睡眠不释放锁,B只能等A睡醒后释放锁在执行。

3、新增一个普通的hello方法,先打印邮件还是短信?

class Phone {
    public synchronized void sendEmail() throws Exception {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("send email...");
    }

    public synchronized void sendSMS() {
        System.out.println("send SMS...");
    }

    public void hello() {
        System.out.println("send SMS...");
    }
}

public class Lock8 {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        new Thread(() -> {
            try {
                phone.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "A").start();
        TimeUnit.MILLISECONDS.sleep(200);
        new Thread(() -> phone.hello(), "A").start();

    }
}

答案:
send SMS…
send email…

分析:hello() 方法并不是同步方法,因此不受锁的影响。

4、两部手机,先打印邮件还是短信?

class Phone {
    public synchronized void sendEmail() throws Exception {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("send email...");
    }

    public synchronized void sendSMS() {
        System.out.println("send SMS...");
    }
}

public class Lock8 {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        Phone phone2 = new Phone();
        new Thread(() -> {
            try {
                phone.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "A").start();
        TimeUnit.MILLISECONDS.sleep(200);
        new Thread(() -> phone2.sendSMS(), "A").start();

    }
}

答案:
send SMS…
send email…

分析:synchronized锁的是对象,两个对象互不影响。

5、两个静态同步方法,先打印邮件还是短信?

class Phone {
    public static synchronized void sendEmail() throws Exception {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("send email...");
    }

    public static synchronized void sendSMS() {
        System.out.println("send SMS...");
    }
}

public class Lock8 {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        new Thread(() -> {
            try {
                phone.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "A").start();
        TimeUnit.MILLISECONDS.sleep(200);
        new Thread(() -> phone.sendSMS(), "A").start();

    }
}

答案:
send email…
send SMS…

分析:此时是类锁,锁的是Phone.class。

6、两个静态同步方法,两个手机,先打印邮件还是短信?

class Phone {
    public static synchronized void sendEmail() throws Exception {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("send email...");
    }

    public static synchronized void sendSMS() {
        System.out.println("send SMS...");
    }
}

public class Lock8 {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        Phone phone2 = new Phone();
        new Thread(() -> {
            try {
                phone.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "A").start();
        TimeUnit.MILLISECONDS.sleep(200);
        new Thread(() -> phone2.sendSMS(), "A").start();

    }
}

答案:
send email…
send SMS…

分析:static方法全局共享,所以不管有多少手机,访问的都是同一个方法。

7、一个普通同步方法,一个静态同步方法,一部手机,先打印邮件还是短信?

class Phone {
    public static synchronized void sendEmail() throws Exception {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("send email...");
    }

    public static synchronized void sendSMS() {
        System.out.println("send SMS...");
    }

    public synchronized void hello() {
        System.out.println("send SMS...");
    }
}

public class Lock8 {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        Phone phone2 = new Phone();
        new Thread(() -> {
            try {
                phone.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "A").start();
        TimeUnit.MILLISECONDS.sleep(200);
        new Thread(() -> phone.hello(), "A").start();

    }
}

答案:
send SMS…
send email…

分析:锁对象不同,一个锁的是Phone.class,一个锁的是this。

8、一个普通同步方法,一个静态同步方法,两部手机,先打印邮件还是短信?

class Phone {
    public static synchronized void sendEmail() throws Exception {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("send email...");
    }

    public static synchronized void sendSMS() {
        System.out.println("send SMS...");
    }

    public synchronized void hello() {
        System.out.println("send SMS...");
    }
}

public class Lock8 {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        Phone phone2 = new Phone();
        new Thread(() -> {
            try {
                phone.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "A").start();
        TimeUnit.MILLISECONDS.sleep(200);
        new Thread(() -> phone2.hello(), "A").start();

    }
}

答案:
send SMS…
send email…

分析:同7。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值