Lock 8锁问题

14 篇文章 0 订阅

最初资源类

class Phone //资源类
{
    public  synchronized void sendEmail()
    {
        System.out.println("-----sendEmail");
    }

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

}

题目

/**
 * 题目:谈谈你对多线程锁的理解,8锁案例说明
 * 口诀:线程   操作  资源类
 * 8锁案例说明:
 * 1 标准访问有ab两个线程,请问先打印邮件还是短信
 * 2 sendEmail方法中加入暂停3秒钟,请问先打印邮件还是短信
 * 3 添加一个普通的hello方法,请问先打印邮件还是hello
 * 4 有两部手机,请问先打印邮件还是短信
 * 5 有两个静态同步方法,有1部手机,请问先打印邮件还是短信
 * 6 有两个静态同步方法,有2部手机,请问先打印邮件还是短信
 * 7 有1个静态同步方法,有1个普通同步方法,有1部手机,请问先打印邮件还是短信
 * 8 有1个静态同步方法,有1个普通同步方法,有2部手机,请问先打印邮件还是短信**/

第一题

1 标准访问有ab两个线程,请问先打印邮件还是短信

资源类

class Phone //资源类
{
    public  synchronized void sendEmail()
    {
       
        System.out.println("-----sendEmail");
    }

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

  
}

测试

public class Lock8Demo
{
    public static void main(String[] args)//一切程序的入口
    {
        Phone phone = new Phone();


        new Thread(() -> {
            phone.sendEmail();
        },"a").start();

        //暂停毫秒,保证a线程先启动
        try { TimeUnit.MILLISECONDS.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }

        new Thread(() -> {
            phone.sendSMS();
        },"b").start();
    }
}

结果

-----sendEmail
-----sendSMS

 

第二题

2 sendEmail方法中加入暂停3秒钟,请问先打印邮件还是短信

资源类

class Phone //资源类
{
    public  synchronized void sendEmail()
    {
        try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
        System.out.println("-----sendEmail");
    }

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


    

}

测试

public class Lock8Demo
{
    public static void main(String[] args)//一切程序的入口
    {
        Phone phone = new Phone();


        new Thread(() -> {
            phone.sendEmail();
        },"a").start();

        //暂停毫秒,保证a线程先启动
        try { TimeUnit.MILLISECONDS.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }

        new Thread(() -> {
            phone.sendSMS();
        },"b").start();
    }
}

结果

-----sendEmail
-----sendSMS

第三题

3 添加一个普通的hello方法,请问先打印邮件还是hello

资源类

class Phone //资源类
{
    public synchronized void sendEmail() {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("-----sendEmail");
    }


    public void hello() {

        System.out.println("-----hello");
    }

}

测试

public class Lock8Demo
{
    public static void main(String[] args)//一切程序的入口
    {
        Phone phone = new Phone();


        new Thread(() -> {
            phone.sendEmail();
        },"a").start();

        //暂停毫秒,保证a线程先启动
        try { TimeUnit.MILLISECONDS.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }

        new Thread(() -> {
            phone.hello();
        },"b").start();
    }
}

结果

-----hello
-----sendEmai

 第四题

4 有两部手机,请问先打印邮件还是短信

资源类

class Phone //资源类
{
    public synchronized void sendEmail() {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("-----sendEmail");
    }

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




}

测试

public class Lock8Demo {
    public static void main(String[] args)//一切程序的入口
    {
        // 第一个手机
        Phone phone = new Phone();

        // 第二个手机
        Phone phone2 = new Phone();

        new Thread(() -> {
            phone.sendEmail();
        }, "a").start();

        //暂停毫秒,保证a线程先启动
        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(() -> {
            phone2.sendSMS();
        }, "b").start();
    }
}

结果

-----sendSMS
-----sendEmail

 第五题

有两个静态同步方法,有1部手机,请问先打印邮件还是短信

资源类

class Phone //资源类
{
    public static synchronized void sendEmail() {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("-----sendEmail");
    }

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



}

测试

public class Lock8Demo {
    public static void main(String[] args)//一切程序的入口
    {
        Phone phone = new Phone();


        new Thread(() -> {
            phone.sendEmail();
        }, "a").start();

        //暂停毫秒,保证a线程先启动
        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(() -> {
            phone.sendSMS();
        }, "b").start();
    }
}

结果

-----sendEmail
-----sendSMS

 第六题

有两个静态同步方法,有2部手机,请问先打印邮件还是短信

资源类

class Phone //资源类
{
    public static synchronized void sendEmail() {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("-----sendEmail");
    }

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




}

测试


public class Lock8Demo {
    public static void main(String[] args)//一切程序的入口
    {
        Phone phone = new Phone();

        Phone phone2 = new Phone();

        new Thread(() -> {
            phone.sendEmail();
        }, "a").start();

        //暂停毫秒,保证a线程先启动
        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(() -> {
            phone2.sendSMS();
        }, "b").start();
    }
}

结果

-----sendEmail
-----sendSMS

 第七题

有1个静态同步方法,有1个普通同步方法,有1部手机,请问先打印邮件还是短信

资源类

class Phone //资源类
{
    public static synchronized void sendEmail() {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("-----sendEmail");
    }

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



}

测试


public class Lock8Demo {
    public static void main(String[] args)//一切程序的入口
    {
        Phone phone = new Phone();

    

        new Thread(() -> {
            phone.sendEmail();
        }, "a").start();

        //暂停毫秒,保证a线程先启动
        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(() -> {
            phone.sendSMS();
        }, "b").start();
    }
}

结果

-----sendSMS
-----sendEmail

 第八题

有1个静态同步方法,有1个普通同步方法,有2部手机,请问先打印邮件还是短信

资源类

class Phone //资源类
{
    public static synchronized void sendEmail() {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("-----sendEmail");
    }

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



}

测试


public class Lock8Demo {
    public static void main(String[] args)//一切程序的入口
    {
        Phone phone = new Phone();

        Phone phone2 = new Phone();

        new Thread(() -> {
            phone.sendEmail();
        }, "a").start();

        //暂停毫秒,保证a线程先启动
        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(() -> {
            phone2.sendSMS();
        }, "b").start();
    }
}

结果

-----sendSMS
-----sendEmail

其余问题

9  有1个静态同步方法,有1个普通方法,有1部手机,请问先打印邮件还是hello

 资源类

class Phone //资源类
{
    public static synchronized void sendEmail() {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("-----sendEmail");
    }

    public void hello() {

        System.out.println("-----hello");
    }


}

测试


public class Lock8Demo {
    public static void main(String[] args)//一切程序的入口
    {
        Phone phone = new Phone();

       

        new Thread(() -> {
            phone.sendEmail();
        }, "a").start();

        //暂停毫秒,保证a线程先启动
        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(() -> {
            phone.hello();
        }, "b").start();
    }
}

结果

-----hello
-----sendEmail

10  有1个静态同步方法,有1个普通方法,有2部手机,请问先打印邮件还是hello

 资源类

class Phone //资源类
{
    public static synchronized void sendEmail() {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("-----sendEmail");
    }

    public void hello() {

        System.out.println("-----hello");
    }


}

测试


public class Lock8Demo {
    public static void main(String[] args)//一切程序的入口
    {
        Phone phone = new Phone();

       Phone phone2 = new Phone();

        new Thread(() -> {
            phone.sendEmail();
        }, "a").start();

        //暂停毫秒,保证a线程先启动
        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(() -> {
            phone2.hello();
        }, "b").start();
    }
}

结果

-----hello
-----sendEmail

注意

 阿里巴巴开发手册提到

原理

第一题和第二题

因为使用的是同一个对象锁 ,只要一个对象里面如果有多个synchronized方法,某一个时刻内,只要一个线程去调用其中的一个synchronized方法了, 其它的线程都只能等待,换句话说,某一个时刻内,只能有唯一的一个线程去访问这些synchronized方法

锁的是当前对象this,被锁定后,其它的线程都不能进入到当前对象的其它的synchronized方法



第三题

 一个对象  加个普通方法后发现和同步锁无关  所以先普通方法先执行

第四题

有2个对象,所以有2个不同的对象锁,情况会改变

第五题 和第六条

一个对象 或2个对象,有1个或2个不同的对象锁,但是 2个同步方法均都是 static 修饰的 所以这2个静态同步方法是属于 Class 的方法 , 对于静态同步方法,锁的是当前类的为为一个模板Class对象,如Phone.class唯一的一个模板。所以会按照 谁先调用的静态同步方法谁就先执行。

第七题和第八题

一个对象 或2个对象,有1个或2个不同的对象锁 ,但是 有一个 静态同步方法 和一个普通同步方法 ,所以静态同步方法,锁的是当前类的为为一个模板Class对象,而普通同步方法是锁的是当前对象this 即对象锁,所以 这两把锁是两个不同的对象,所以静态同步方法与普通同步方法之间是不会有竞态条件的 但是一旦一个静态同步方法获取锁后,其他的静态同步方法都必须等待该方法释放锁后才能获取锁。

至于第九题和第十题 

一个对象 或2个对象,有1个或2个不同的对象锁,但是 有一个 静态同步方法 和一个普通方法,

普通方法与同步锁无关,所以普通先执行

总结

同一对象:

 同一对象访问不同的同步锁,是按照顺序执行

同一对象访问同步锁与普通方法,是执行普通方法

同一对象访问不同静态同步锁,按照谁先调用谁先执行

同一对象访问一个静态同步锁,一个同步锁,先执行同步锁

多个对象

多个对象访问不同同步锁,按照顺序执行 

不同对象访问不同静态同步锁,按照谁先调用谁先执行

不同对象访问一个静态同步锁,一个同步锁,先执行同步锁即先出同步锁在出静态同步锁

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值