JUC 并发编程--03, 深刻理解锁, 8 锁现象,
如何判断锁的是谁? 永远知道是什么锁,
线程8锁:就是关于锁的8个问题
问题1:
public class LockDemo01 {
public static void main(String[] args) throws InterruptedException {
//8 锁--1
//资源类
Phone phone = new Phone();
new Thread(()->{ phone.sendMes();},"A").start();
//这里睡1 秒, 保证线程B 能抢到执行权
TimeUnit.SECONDS.sleep(1);
new Thread(()->{ phone.call(); },"B").start();
//问: 此时是先打印: 发信息? 还是打电话,
//答: 先信息, 后打电话 因为资源类中的二个方法 都是 synchronized 修饰的, 他锁的是方法的调用者,由于调用者都是phone, 同一个调用者,所以谁先拿到锁,谁先执行
}
}
//资源类
class Phone{
//发短信
public synchronized void sendMes(){
//这里睡4秒
try {
TimeUnit.SECONDS.sleep(4);
System.out.println("发短消息");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//打电话
public synchronized void call(){
System.out.println("打电话");
}
}
问题2: 资源类中的 call()方法是普通方法, sendMes()是synchronized修饰的, 此时打印结果是什么? 谁先执行?, 答案是: 打电话, 发信息
public class LockDemo01 {
public static void main(String[] args) throws InterruptedException {
//8 锁--1
//资源类
Phone phone = new Phone();
new Thread(()->{ phone.sendMes();},"A").start();
//这里睡1 秒, 保证线程B 能抢到执行权
TimeUnit.SECONDS.sleep(1);
new Thread(()->{ phone.call(); },"B").start();
//问: 此时是先打印: 发信息? 还是打电话,
//答: 打电话 发信息 因为资源类sendMes()是 synchronized修饰,锁对象是调用者, call()是普通方法, 线程调用互不影响,
}
}
//资源类
class Phone{
//发短信
public synchronized void sendMes(){
//这里睡4秒
try {
TimeUnit.SECONDS.sleep(4);
System.out.println("发短消息");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//打电话
public void call(){
System.out.println("打电话");
}
}
问题3: 资源类中的二个方法都是 synchronized修饰的, 此时有二个调用者,谁先执行? 结果为什么?
public class LockDemo01 {
public static void main(String[] args) throws InterruptedException {
//8 锁--1
//资源类
Phone phone1 = new Phone();
Phone phone2 = new Phone();
new Thread(()->{ phone1.sendMes();},"A").start();
//这里睡1 秒, 保证线程B 能抢到执行权
TimeUnit.SECONDS.sleep(1);
new Thread(()->{ phone2.call(); },"B").start();
//问: 此时是先打印: 发信息? 还是打电话,
//答: 打电话 发短信 因为资源类中的二个方法 都是 synchronized 修饰的, 他锁的是方法的调用者,由于调用者是二个, 二把锁, 互不干扰 ,
}
}
//资源类
class Phone{
//发短信
public synchronized void sendMes(){
//这里睡4秒
try {
TimeUnit.SECONDS.sleep(4);
System.out.println("发短消息");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//打电话
public synchronized void call(){
System.out.println("打电话");
}
}
问题4: 资源类中的二个方法都是 static synchronized修饰的, 此时同一个调用者, 结果先打印谁?
public class LockDemo01 {
public static void main(String[] args) throws InterruptedException {
//8 锁--1
//资源类
Phone phone = new Phone();
new Thread(()->{ phone.sendMes();},"A").start();
//这里睡1 秒, 保证线程B 能抢到执行权
TimeUnit.SECONDS.sleep(1);
new Thread(()->{ phone.call(); },"B").start();
//问: 此时是先打印: 发信息? 还是打电话,
//答: 发短信 打电话 因为资源类中的二个方法 都是 synchronized static 修饰的静态同步类,是在类加载的时候就有了锁,锁的是同一个class,所以这个锁,谁先拿到,谁先执行
}
}
//资源类
class Phone{
//发短信
public static synchronized void sendMes(){
//这里睡4秒
try {
TimeUnit.SECONDS.sleep(4);
System.out.println("发短消息");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//打电话
public static synchronized void call(){
System.out.println("打电话");
}
}
问题5: 资源类中的二个方法都是 static synchronized修饰的, 此时二个调用者, 结果先打印谁?
public class LockDemo01 {
public static void main(String[] args) throws InterruptedException {
//8 锁--1
//资源类
Phone phone1 = new Phone();
Phone phone2 = new Phone();
new Thread(()->{ phone1.sendMes();},"A").start();
//这里睡1 秒, 保证线程B 能抢到执行权
TimeUnit.SECONDS.sleep(1);
new Thread(()->{ phone2.call(); },"B").start();
//问: 此时是先打印: 发信息? 还是打电话,
//答: 发短信 打电话 因为资源类中的二个方法 都是 synchronized static 修饰的静态同步方法,是在类加载的时候就有了锁,锁对象是class, 此时不管多少个调用者,所以这个锁,谁先拿到,谁先执行
}
}
//资源类
class Phone{
//发短信
public static synchronized void sendMes(){
//这里睡4秒
try {
TimeUnit.SECONDS.sleep(4);
System.out.println("发短消息");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//打电话
public static synchronized void call(){
System.out.println("打电话");
}
}
问题6:资源类的方法,一个是 static synchronized 修饰的静态同步方法, 一个是synchronized 修饰, 同一个调用者, 此时谁先打印??
public class LockDemo01 {
public static void main(String[] args) throws InterruptedException {
//资源类
Phone phone = new Phone();
new Thread(()->{ phone.sendMes();},"A").start();
//这里睡1 秒, 保证线程B 能抢到执行权
TimeUnit.SECONDS.sleep(1);
new Thread(()->{ phone.call(); },"B").start();
//问: 此时是先打印: 发信息? 还是打电话,
//答: 打电话 发短信 ,因为资源类中sednMes()是静态同步方法,锁的是class对象, call()方法是普通同步方法,锁的是调用者,相当于二把锁,互不干扰,sendMes,睡的时间长,所以后打印
}
}
//资源类
class Phone{
//发短信
public static synchronized void sendMes(){
//这里睡4秒
try {
TimeUnit.SECONDS.sleep(4);
System.out.println("发短消息");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//打电话
public synchronized void call(){
System.out.println("打电话");
}
}
问题7 资源类的方法,一个是 static synchronized 修饰的静态同步方法, 一个是synchronized 修饰, 有二个调用者, 此时谁先打印??
public class LockDemo01 {
public static void main(String[] args) throws InterruptedException {
//资源类
Phone phone1 = new Phone();
Phone phone2 = new Phone();
new Thread(()->{ phone1.sendMes();},"A").start();
//这里睡1 秒, 保证线程B 能抢到执行权
TimeUnit.SECONDS.sleep(1);
new Thread(()->{ phone2.call(); },"B").start();
//问: 此时是先打印: 发信息? 还是打电话,
//答: 打电话 发短信 ,因为资源类中sednMes()是静态同步方法,锁的是class对象, call()方法是普通同步方法,锁的是调用者,相当于二把锁,互不干扰,sendMes,睡的时间长,所以后打印
}
}
//资源类
class Phone{
//发短信
public static synchronized void sendMes(){
//这里睡4秒
try {
TimeUnit.SECONDS.sleep(4);
System.out.println("发短消息");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//打电话
public synchronized void call(){
System.out.println("打电话");
}
}