线程8锁问题

本文通过一个Java多线程的例子,深入探讨了同步方法的执行顺序、锁的机制以及静态同步方法的影响。总结了线程访问同步方法的规则,并分析了不同锁类型对程序执行的影响,揭示了Java并发编程中的锁概念。

1、线程8锁问题

1.1、代码

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

    public synchronized void sendMs() {
        System.out.println("*******sendMs");
    }

    public void sayHello() {
        System.out.println("*****sayHello");
    }
}

测试demo

public class LockDemo {

    public static void main(String[] args) throws Exception {
        Resource resource = new Resource();
        new Thread(() -> resource.sendEmail(), "A").start();
        Thread.sleep(100);
        new Thread(() -> resource.sendMs(), "B").start();
    }
}

1.2、锁的8问?

1.2.1、问题
 1.  标准访问(两个普通同步方法 sendEmail 和 sendMs),1个资源,两线程中间睡眠 100 毫秒,先打印邮件还是短信?
 2. 标准访问(两个普通同步方法 sendEmail 和 sendMs),1个资源,在 sendEmail() 方法中睡眠 4 秒,先打印邮件还是短信?
 3. 添加普通的 hello() 方法,1个资源,先打印邮件还是 hello?
 4. 2个资源,先打印邮件还是短信?
 5. 2个静态同步方法(sendEmail 和 sendMs),1个资源,先打印邮件还是短信?
 6. 2个静态同步方法(sendEmail 和 sendMs),2个资源,先打印邮件还是短信?
 7. 1个静态同步方法(sendEmail),1个普通同步方法(sendMs)1个资源,先打印邮件还是短信?
 8. 1个静态同步方法(sendEmail),1个普通同步方法(sendMs)2个资源,先打印邮件还是短信?
1.2.2、答案
  1. 标准访问,先打印邮件
  2. 邮件设置暂停4秒方法,先打印邮件
		对象锁
	       一个对象里面如果有多个synchronized方法,某一个时刻内,只要一个线程去调用其中的一个synchronized方法了,
	       其他的线程都只能等待,换句话说,某一个时刻内,只能有唯一一个线程去访问这些synchronized方法,
	       锁的是当前对象this,被锁定后,其他的线程都不能进入到当前对象的其他的synchronized方法	       
  3. 新增sayHello方法,先打印sayHello
       加个普通方法后发现和同步锁无关
  4. 两个资源,先打印短信
       换成两个对象后,不是同一把锁了,情况立刻变化
  5. 两个静态同步方法,同一个资源,先打印邮件
  6. 两个静态同步方法,同两个资源,先打印邮件,锁的同一个字节码对象
       静态同步方法锁的是Class,是全局锁
       synchronized实现同步的基础:java中的每一个对象都可以作为锁。
       具体表现为一下3中形式。
       对于普通同步方法,锁是当前实例对象,锁的是当前对象this,
       对于静态同步方法,锁是当前类的class对象
       对于同步方法块,锁的是synchronized括号里配置的对象。
  7. 一个静态同步方法,一个普通同步方法,同一个资源,先打印短信
  8. 一个静态同步方法,一个普通同步方法,同二个资源,先打印短信
       静态同步方法锁的是CLass,普通同步方法锁的是对象 加锁的位置不一样,相互无影响
1.2.2、总结
1.当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁。
也就是说如果一个实例对象的普通同步方法获取锁后,该实例对象的其他普通同步方法必须等待获取锁的方法释放锁后才能获取锁,
但是别的实例对象的普通同步方法因为跟该实例对象的普通同步方法用的是不同的锁,
所以无需等待该实例对象已获取锁的普通同步方法释放锁就可以获取他们自己的锁。
 
2.这两把锁(this/Class)是两个不同的对象,所以静态同步方法与非静态同步方法之间是不会有影响的。
 
3.所有的静态同步方法用的也是同一把锁--类对象本身(Class),
一个静态同步方法获取锁后,其他的静态同步方法都必须等待该方法释放锁后才能获取锁,
不管是同一个实例对象的静态同步方法之间,还是不同的实例对象的静态同步方法之间,只要它们同一个类产生的实例对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

后端技术那点事

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值