八锁现象彻底理解锁

如何判断锁的是谁?知道什么是锁?
1.标准情况下,两个线程先打印发短信还是打电话?—》发短信
2.sendMag延迟四秒,两个线程先打印发短信还是打电话?—》发短信

package com.liao.Lock8;
import java.util.concurrent.TimeUnit;
/**
 * 八锁:就是关于锁的八个问题
 * 1.标准情况下,两个线程先打印发短信还是打电话?---》发短信
 * 2.sendMag延迟四秒,两个线程先打印发短信还是打电话?---》发短信
 */
public class Test1 {
    public static void main(String[] args) {
        //调用者
        Phone phone = new Phone();
        new Thread(()->{
            phone.sendMag();
        },"A").start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(()->{
            phone.Call();
        },"B").start();
    }
}
class Phone{
    //synchronized 锁的对象是方法的调用者!phone
    //两个方法用的是同一个锁,谁先拿到谁就执行
    public synchronized void sendMag(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }
    public synchronized void Call(){
        System.out.println("打电话");
    }
}

2.增加一个普通方法后,先输出hello,因为hello是普通方法,这里没有锁,不是同步方法,不受锁的影响!

package com.liao.Lock8;

import java.util.concurrent.TimeUnit;

/**
 * 3.增加一个普通方法后,先执行发短信还是先hello?---》hello
 */
public class Test2 {
    public static void main(String[] args) {
        //调用者,两个对象
        Phone1 phone = new Phone1();
        new Thread(()->{
            phone.sendMag();
        },"A").start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(()->{
            phone.hello();
        },"B").start();
    }
}
class Phone1{
    //synchronized 锁的对象是方法的调用者!phone
    //
    public synchronized void sendMag(){
        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");
    }
}

3.当对象变成两个以后,两个同步方法,先执行发短信还是先打电话?—》打电话,因为两个对象拿的锁不一样,没有延迟的先执行

package com.liao.Lock8;

import java.util.concurrent.TimeUnit;

/**
 * 3.增加一个普通方法后,先执行发短信还是先hello?---》hello
 * 4.两个对象,两个同步方法,先执行发短信还是先打电话?---》打电话
 */
public class Test2 {
    public static void main(String[] args) {
        //调用者,两个对象,两把锁
        Phone1 phone1 = new Phone1();
        Phone1 phone2 = new Phone1();
        new Thread(()->{
            phone1.sendMag();
        },"A").start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(()->{
            phone2.Call();
        },"B").start();
    }
}
class Phone1{
    //synchronized 锁的对象是方法的调用者!phone
    //
    public synchronized void sendMag(){
        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");
    }
}

4.增加两个静态的同步方法,只有一个对象,先打印发短信还是打电话-----》发短信,static 静态方法,类一加载就有了,锁的是Class对象,Phone3只有一个Class对象

package com.liao.Lock8;

import java.util.concurrent.TimeUnit;
/**
 * 5.增加两个静态的同步方法,只有一个对象,先打印发短信还是打电话-----》发短信
 */
public class Test3 {
    public static void main(String[] args) {
        //调用者
        Phone2 phone1 = new Phone2();
        new Thread(()->{
            phone1.sendMag();
        },"A").start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(()->{
            phone1.Call();
        },"B").start();
    }
}
class Phone2{
    //synchronized 锁的对象是方法的调用者!phone
    //static 静态方法
    //类一加载就有了,锁的是Class对象
    //Phone3只有一个Class对象
    public static synchronized void sendMag(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }
    public static synchronized void Call(){
        System.out.println("打电话");
    }
}

5.两个对象!两个静态的同步方法,两个对象,先打印发短信还是打电话-----》发短信,两个对象的Class类模板只有一个,static,锁的是Class

package com.liao.Lock8;

import java.util.concurrent.TimeUnit;
/**
 * 5.增加两个静态的同步方法,只有一个对象,先打印发短信还是打电话-----》发短信
 * 6.两个对象!两个静态的同步方法,两个对象,先打印发短信还是打电话-----》发短信
 */
public class Test3 {
    public static void main(String[] args) {
        //两个对象的Class类模板只有一个,static,锁的是Class
        Phone2 phone1 = new Phone2();
        Phone2 phone2 = new Phone2();
        new Thread(()->{
            phone1.sendMag();
        },"A").start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(()->{
            phone2.Call();
        },"B").start();
    }
}
class Phone2{
    //synchronized 锁的对象是方法的调用者!phone
    //static 静态方法
    //类一加载就有了,锁的是Class对象
    //Phone3只有一个Class对象
    public static synchronized void sendMag(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }
    public static synchronized void Call(){
        System.out.println("打电话");
    }
}

6.一个静态同步方法,一个普通同步方法,先发短信还是打电话—》打电话,普通同步方法,锁的调用者,static锁的Class,两把锁不一样,所以不需要等待

package com.liao.Lock8;
import java.util.concurrent.TimeUnit;
/**
 * 7.一个静态同步方法,一个普通同步方法,先发短信还是打电话---》打电话
 *
 */
public class Test4 {
    public static void main(String[] args) {
        //两个对象的Class类模板只有一个,static,锁的是Class
        Phone3 phone1 = new Phone3();
        new Thread(()->{
            phone1.sendMag();
        },"A").start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(()->{
            phone1.Call();
        },"B").start();
    }
}
class Phone3{
    //synchronized 锁的对象是方法的调用者!phone
    //static 静态方法
    //类一加载就有了,锁的是Class对象
    //
    public static synchronized void sendMag(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }
    //普通同步方法,锁的调用者
    public synchronized void Call(){
        System.out.println("打电话");
    }
}

7.一个静态同步方法,一个普通同步方法,两个对象,先发短信还是打电话—》打电话,和第七个一样,普通同步方法,锁的调用者,static锁的Class,两把锁不一样,所以不需要等待

package com.liao.Lock8;

import java.util.concurrent.TimeUnit;

/**
 * 7.一个静态同步方法,一个普通同步方法,先发短信还是打电话---》打电话
 * 8.一个静态同步方法,一个普通同步方法,两个对象,先发短信还是打电话---》打电话
 *
 */
public class Test4 {
    public static void main(String[] args) {
        //两个对象的Class类模板只有一个,static,锁的是Class
        Phone3 phone1 = new Phone3();
        Phone3 phone2 = new Phone3();
        new Thread(()->{
            phone1.sendMag();
        },"A").start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(()->{
            phone2.Call();
        },"B").start();
    }
}
class Phone3{
    //synchronized 锁的对象是方法的调用者!phone
    //static 静态方法
    //类一加载就有了,锁的是Class对象
    //
    public static synchronized void sendMag(){
        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
发出的红包

打赏作者

Marlboro~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值