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),
一个静态同步方法获取锁后,其他的静态同步方法都必须等待该方法释放锁后才能获取锁,
不管是同一个实例对象的静态同步方法之间,还是不同的实例对象的静态同步方法之间,只要它们同一个类产生的实例对象

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

被折叠的 条评论
为什么被折叠?



