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("打电话");
    }

}
posted @ 2020-08-10 21:48  死不了好气呦  阅读(165)  评论(0编辑  收藏  举报