java之锁问题:
学习B站狂神视频总结:
代码不执行,仅示例参考
import java.util.concurrent.TimeUnit;
public class Lock {
public static void main(String[] args) {
Phone phone = new Phone();
Phone phone1 = new Phone();
Phone phone2 = new Phone();
new Thread(()->{
//phone.sendSms();
phone1.sendSms();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
//phone.call();
phone2.call();
},"B").start();
}
}
class Phone{
public static synchronized void sendSms(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public static synchronized void call(){
System.out.println("打电话");
}
public void listening(){
System.out.println("听歌");
}
}
synchronized加锁:重度锁,谁拿到锁就会阻塞,必须执行完才会释放
锁的对象是方法的调用者,谁先拿到谁执行
锁方法的时候:锁的是类的实例,谁先拿到锁谁就执行
注:没有锁的普通方法不受锁的影响
环境:
创建AB线程,休眠1毫秒,控制A先创建B后创建
两个方法:发短信需要4毫秒休眠才执行,打电话直接执行
序号 | 同步方法 | 静态同步方法 | 对象 | 执行结果分析 |
---|---|---|---|---|
1 | 2 | 1 | 发短信:一把锁,线程A先拿到锁先执行 | |
2 | 2 | 2 | 打电话:两把锁,发短信不需要睡眠先执行 | |
3 | 2 | 1 | 发短信:唯一类锁, 线程A先拿到 | |
4 | 2 | 2 | 发短信:唯一类锁, 线程A先拿到 | |
5 | 1 | 1 | 1 | 打电话:两个锁,一个锁类模板,一个锁调用者,不存在线程等待问题,按照方法睡眠时间执行 |
6 | 1 | 1 | 2 | 打电话:两个方法用的不是同一个锁,互不影响 |
1.两个同步方法;一个对象
2.两个同步方法;两个对象(即两个调用者,两把锁)
此时根据睡眠时间执行
3.两个静态同步方法(static):static方法在类加载时就有了,锁的是Class对象(每个类唯一);
两个静态同步方法,如果是两个对象
也只有一个类模板,锁的是Class;不受创建对象数量的影响
4.普通同步方法,静态同步方法,一个对象
普通同步方法 锁的是Class模板
静态同步方法 锁的是调用者
两个方法用的不是同一个锁,互不影响
5.普通同步方法,静态同步方法,两个对象
普通同步方法 锁的是Class模板
静态同步方法 锁的是调用者
两个方法用的不是同一个锁,互不影响
总结:
new :具体的对象
static:唯一的Class模板
如果是同一个锁,就看谁先拿到锁;如果不是同一个锁,就看睡眠了