8锁现象

8锁,关于锁的8个问题

1、标准情况下,两个线程先打印 发短信 还是 打电话?发短信

2、sendMsm延迟4秒,两个线程先打印 发短信 还是 打电话?发短信


public class Test1 {
    public static void main(String[] args) {
        Phone phone = new Phone();

        new Thread(() -> {
            phone.sendMsg();
        }, "A").start();

        try{
            TimeUnit.SECONDS.sleep(1);
        } catch (Exception e) {
            e.printStackTrace();
        }

        new Thread(() -> {
            phone.call();
        }, "B").start();
    }
}

class Phone {

    //synchronized 锁的对象时方法的调用者!
    //两个方法是同一个锁,谁先拿到谁执行

    public synchronized void sendMsg(){
        try{
            TimeUnit.SECONDS.sleep(4);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public synchronized void call() {
        System.out.println("打电话");
    }
}

3、增加一个普通方法,先打印 发短信 还是 hello? hello
4、两个对象,两个同步方法,先打印 发短信 还是 打电话? 打电话

public class Test2 {
    public static void main(String[] args) {
        Phone2 phone1 = new Phone2();
        Phone2 phone2 = new Phone2();

        new Thread(() -> {
            phone1.sendMsg();
        }, "A").start();

        try{
            TimeUnit.SECONDS.sleep(1);
        } catch (Exception e) {
            e.printStackTrace();
        }

        new Thread(() -> {
            phone1.hello();
        }, "B").start();

        new Thread(() -> {
            phone2.call();
        }, "B").start();
    }
}

class Phone2 {

    //synchronized 锁的对象时方法的调用者!
    public synchronized void sendMsg(){
        try{
            TimeUnit.SECONDS.sleep(4);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public synchronized void call() {
        System.out.println("打电话");
    }

    //这里没有锁!不是同步方法,不受所得影响
    public void hello() {
        System.out.println("hello hello");
    }
}

5、增加两个静态变量,只有一个对象,先打印 发短信 还是 打电话? 发短信
6、增加两个静态变量,两个对象,先打印 发短信 还是 打电话? 发短信

public class Test3 {
    public static void main(String[] args) {
        //两个对象的Class模板只有一个
        Phone3 phone1 = new Phone3();
        Phone3 phone2 = new Phone3();

        new Thread(() -> {
            phone1.sendMsg();
        }, "A").start();

        try{
            TimeUnit.SECONDS.sleep(1);
        } catch (Exception e) {
            e.printStackTrace();
        }

        new Thread(() -> {
            phone1.call();
        }, "B").start();

        new Thread(() -> {
            phone2.call();
        }, "B").start();

    }
}

//Phone3只有唯一的一个Class对象
class Phone3 {

    //synchronized 锁的对象时方法的调用者!
    //static 静态方法,类一加载就有了,锁的是Class
    public static synchronized void sendMsg(){
        try{
            TimeUnit.SECONDS.sleep(4);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public static synchronized void call() {
        System.out.println("打电话");
    }

}

7、一个普通同步方法,一个静态同步方法,一个对象,先打印发短信还是打电话? 打电话
8、一个普通同步方法,一个静态同步方法,两个个对象,先打印发短信还是打电话? 打电话

public class Test4 {
    public static void main(String[] args) {
        Phone4 phone = new Phone4();
        Phone4 phone2 = new Phone4();

        new Thread(() -> {
            phone.sendMsg();
        }, "A").start();

        try{
            TimeUnit.SECONDS.sleep(1);
        } catch (Exception e) {
            e.printStackTrace();
        }

        new Thread(() -> {
            phone2.call();
        }, "B").start();
    }
}

class Phone4 {

    //锁的是Class类模板
    public static synchronized void sendMsg(){
        try{
            TimeUnit.SECONDS.sleep(4);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    //锁的是调用者
    public synchronized void call() {
        System.out.println("打电话");
    }
}

小结

new 对象,锁具体的一个Phone

static Class 锁唯一的类模板

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容