synchronized锁的8个问题

关于synochronized的八个问题

1 标准访问,先打印短信还是邮件 短信

class Phone
{

    public  synchronized void sendSMS() throws Exception
    {
        
        System.out.println("------sendSMS");
    }
    public synchronized  void sendEmail() throws Exception
    {
        System.out.println("------sendEmail");
    }

    public void getHello()
    {
        System.out.println("------getHello");
    }

}
public class Lock_8
{
    public static void main(String[] args) throws Exception
    {

        Phone phone = new Phone();
        Phone phone2 = new Phone();

        new Thread(() -> {
            try {
                phone.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "AA").start();

        Thread.sleep(100);

        new Thread(() -> {
            try {
                phone.sendEmail();
//                phone.getHello();
//                phone2.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "BB").start();
    }
}

答案是短信,解释如下:标准访问:各线程和个方法中都没有睡眠时间,此时可能先打印短信,也可能先打印邮件,但是在打印短信的线程后面加上睡眠100毫秒,那就是先打印短信,因为一个对象里面如果有多个synchronized方法,某一个时刻内,只要一个线程去调用其中的一个synchronized方法了,其它的线程都只能等待,换句话说,某一个时刻内,只能有唯一一个线程去访问这些synchronized方法

2 停4秒在短信方法内,先打印短信还是邮件 短信

class Phone
{

    public  synchronized void sendSMS() throws Exception
    {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("------sendSMS");
    }
    public synchronized  void sendEmail() throws Exception
    {
        System.out.println("------sendEmail");
    }

    public void getHello()
    {
        System.out.println("------getHello");
    }

}
public class Lock_8
{
    public static void main(String[] args) throws Exception
    {

        Phone phone = new Phone();
        Phone phone2 = new Phone();

        new Thread(() -> {
            try {
                phone.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "AA").start();

        Thread.sleep(1000);

        new Thread(() -> {
            try {
                phone.sendEmail();
//                phone.getHello();
//                phone2.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "BB").start();
    }
}

答案是短信,解释如下:只要打印短信后面有100毫秒的睡眠时间,那么先打印的就是短信,因为一个对象里面如果有多个synchronized方法,某一个时刻内,只要一个线程去调用其中的一个synchronized方法了,其它的线程都只能等待

3 新增普通的hello方法,是先打短信还是hello (短信方法中有睡眠4秒) hello

class Phone
{

    public  synchronized void sendSMS() throws Exception
    {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("------sendSMS");
    }
    public synchronized  void sendEmail() throws Exception
    {
        System.out.println("------sendEmail");
    }

    public void getHello()
    {
        System.out.println("------getHello");
    }

}
public class Lock_8
{
    public static void main(String[] args) throws Exception
    {

        Phone phone = new Phone();
        Phone phone2 = new Phone();

        new Thread(() -> {
            try {
                phone.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "AA").start();

        Thread.sleep(1000);

        new Thread(() -> {
            try {
                //phone.sendEmail();
                phone.getHello();
//                phone2.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "BB").start();
    }
}

答案是hello,只要打印短信的方法中有睡眠4秒的代码,那么就是先打印hello,因为普通方法不在synchronized锁的范围内,所以打印hello的线程不受影响

4 现在有两部手机,先打印短信还是邮件(短信方法中有睡眠4秒) 邮件

class Phone
{

    public  synchronized void sendSMS() throws Exception
    {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("------sendSMS");
    }
    public synchronized  void sendEmail() throws Exception
    {
        System.out.println("------sendEmail");
    }

    public void getHello()
    {
        System.out.println("------getHello");
    }

}
public class Lock_8
{
    public static void main(String[] args) throws Exception
    {

        Phone phone = new Phone();
        Phone phone2 = new Phone();

        new Thread(() -> {
            try {
                phone.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "AA").start();

        Thread.sleep(1000);

        new Thread(() -> {
            try {
                //phone.sendEmail();
                //phone.getHello();
                phone2.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "BB").start();
    }
}

先打印邮件,因为这是两个对象,其各自的线程不再是同一把锁,因为打印短信方法有4秒的延迟,所以先打印邮件

5 两个静态同步方法,1部手机,先打印短信还是邮件(短信方法中有睡眠4秒) 短信

class Phone
{

    public  synchronized static void sendSMS() throws Exception
    {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("------sendSMS");
    }
    public synchronized static void sendEmail() throws Exception
    {
        System.out.println("------sendEmail");
    }

    public void getHello()
    {
        System.out.println("------getHello");
    }

}
public class Lock_8
{
    public static void main(String[] args) throws Exception
    {

        Phone phone = new Phone();
        Phone phone2 = new Phone();

        new Thread(() -> {
            try {
                phone.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "AA").start();

        Thread.sleep(1000);

        new Thread(() -> {
            try {
                //phone.sendEmail();
                //phone.getHello();
                phone2.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "BB").start();
    }
}

答案是短信 解释:synchronized实现同步的基础:Java中的每一个对象都可以作为锁。
具体表现为以下3种形式。
对于普通同步方法,锁是当前实例对象。
对于静态同步方法,锁是当前类的Class对象。
对于同步方法块,锁是Synchonized括号里配置的对象
问题5中synchronized修饰的是静态同步方法,所以锁的是当前类的Class对象,先获取锁的线程先执行,由于打印邮件线程前有100毫秒的延迟,所以打印短信的线程先获取锁,所以先打印短信

6 两个静态同步方法,2部手机,先打印短信还是邮件(短信方法中有睡眠4秒) 短信

class Phone
{

    public  synchronized static void sendSMS() throws Exception
    {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("------sendSMS");
    }
    public synchronized static void sendEmail() throws Exception
    {
        System.out.println("------sendEmail");
    }

    public void getHello()
    {
        System.out.println("------getHello");
    }

}
public class Lock_8
{
    public static void main(String[] args) throws Exception
    {

        Phone phone = new Phone();
        Phone phone2 = new Phone();

        new Thread(() -> {
            try {
                phone.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "AA").start();

        Thread.sleep(1000);

        new Thread(() -> {
            try {
                //phone.sendEmail();
                //phone.getHello();
                phone2.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "BB").start();
    }
}

同上答案相同,也是打印短信,因为synchronized修饰的是两个静态同步方法,锁的是当前类的Class对象,是同一把锁,所以先打印短信

7 1个静态同步方法,1个普通同步方法,1部手机,先打印短信还是邮件(短信方法中有睡眠4秒) 邮件

class Phone
{

    public  synchronized static void sendSMS() throws Exception
    {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("------sendSMS");
    }
    public synchronized  void sendEmail() throws Exception
    {
        System.out.println("------sendEmail");
    }

    public void getHello()
    {
        System.out.println("------getHello");
    }

}
public class Lock_8
{
    public static void main(String[] args) throws Exception
    {

        Phone phone = new Phone();
        Phone phone2 = new Phone();

        new Thread(() -> {
            try {
                phone.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "AA").start();

        Thread.sleep(1000);

        new Thread(() -> {
            try {
                //phone.sendEmail();
                //phone.getHello();
                phone2.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "BB").start();
    }
}

答案是邮件 解释:一个静态同步方法和一个普通方法的synchronized不是同一个锁,虽然修饰静态同步方法的synchronized的锁锁的是当前类的Class对象,但是二者不是同一把锁,所以先打印的是没有延迟的邮件方法

8 1个静态同步方法,1个普通同步方法,2部手机,先打印短信还是邮件(短信方法中有睡眠4秒) 邮件

class Phone
{

    public  synchronized static void sendSMS() throws Exception
    {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("------sendSMS");
    }
    public synchronized  void sendEmail() throws Exception
    {
        System.out.println("------sendEmail");
    }

    public void getHello()
    {
        System.out.println("------getHello");
    }

}
public class Lock_8
{
    public static void main(String[] args) throws Exception
    {

        Phone phone = new Phone();
        Phone phone2 = new Phone();

        new Thread(() -> {
            try {
                phone.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "AA").start();

        Thread.sleep(1000);

        new Thread(() -> {
            try {
                //phone.sendEmail();
                //phone.getHello();
                phone2.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "BB").start();
    }
}

跟上面一样,不是同一把锁,所以先打印的是没有延迟的邮件方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值