java的8锁现象

锁的8个现象我写了4个测试类,每个测试类里两个现象都是相似的!!!

/**
 * 8锁现象
 * 1.先发短信还是先打电话? 答:先发短信,再打电话,因为synchronized 锁的对象是方法的调用者,谁先执行谁先输出
 * 2.在发短信方法中加4秒延时,看先发短信还是先打电话? 答:还是先发短信,再打电话,因为synchronized 锁的对象是方法的调用者,谁先执行谁先输出,即使发短信方法卡着4秒但是锁还没有被释放
 *
 */
public class TestLock1 {
    public static void main(String[] args) {
        Phone phone = new Phone();

        new Thread(() -> phone.sendSms(), "A").start();

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

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

class Phone {

    //synchronized 锁的对象是方法的调用者
    //两个方法是一个调用者,谁先拿到谁先执行
    public synchronized void sendSms() {
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public synchronized void call() {
        System.out.println("打电话");
    }
}
/**
 * 8锁现象
 * 3.加一个普通方法,然后调用,看先发短信还是先输出hello? 答:先输出普通方法hello,在输出发短信
 * 4.两个对象,调用不同的同步方法,先发短信还是先打电话? 答:先打电话,再发短信,因为发短信有延时在阻塞,如果没有阻塞则不一定,哪个对象先抢占到cpu谁先执行
 */
public class TestLock2 {
    public static void main(String[] args) {
        Phone2 phone = new Phone2();
        Phone2 phone1 = new Phone2();

        new Thread(() -> phone.sendSms(), "A").start();

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

//        new Thread(() -> phone.hello(),"B").start();
        new Thread(() -> phone1.call(), "B").start();
    }
}

class Phone2 {

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

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

    //这个方法没有锁,所以不受锁的影响
    public void hello() {
        System.out.println("hello");
    }
}
/**
 * 8锁现象
 * 5.给打电话和发短信加上static关键字,同一个对象再进行调用是先发短信还是先打电话? 答:是先发短信,在打电话,因为两个同步方法都被static修饰,
 * 被static修饰后锁的是类,而非对象,类是全局唯一的所以先调用的发短信在调用的打电话方法,输出的就是先发短信再打电话
 * 6.给打电话和发短信加上static关键字,两个对象进行调用,一个调用发短信,一个调用打电话,是先发短信还是先打电话? 答:先发短信,因为两个同步方法都被static修饰过,
 * 就算是两个对象调用不同的方法,但是被static修饰过的同步方法锁的是同一个Class类模板,所以先调用的发短信在调用的打电话方法,输出的就是先发短信再打电话
 */
public class TestLock3 {
    public static void main(String[] args) {
        //两个对象的Class类模板只有一个,static,锁的是Class
        Phone3 phone = new Phone3();
        Phone3 phone1 = new Phone3();

        new Thread(() -> phone.sendSms(), "A").start();

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

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

//全局唯一的Class
class Phone3 {

    //synchronized 锁的对象是方法的调用者,而被static修饰过的方法为静态方法,类一加载就有了,所以锁的是Class
    //static 静态方法
    //类一加载就有了,锁的是Class
    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("打电话");
    }

}
/**
 * 8锁现象
 * 7.一个静态的同步方法,一个普通的同步方法,一个对象调用,是先发短信还是先打电话? 答:先打电话,因为static修饰的同步方法锁的是Class的类模板,
 * 而普通同步方法锁的是对象,两个不是一个锁,自然是执行快的先输出
 * 8.一个静态的同步方法,一个普通的同步方法,两个对象调用,是先发短信还是先打电话? 答:先打电话,因为static修饰的同步方法锁的是Class的类模板,
 * 而普通同步方法锁的是对象,两个不是一个锁并且不是同一个对象,自然是执行快的先输出
 */
public class TestLock4 {
    public static void main(String[] args) {
        Phone4 phone = new Phone4();
        Phone4 phone1 = new Phone4();

        new Thread(() -> phone.sendSms(), "A").start();

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

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

class Phone4 {

    //静态同步方法,锁的是Class的类模板
    public static synchronized void sendSms() {
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    //普通同步方法,锁的调用者
    public synchronized void call() {
        System.out.println("打电话");
    }

}

如果有感觉不妥的地方请私信我!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值