Java八锁现象


八锁现象

一、简介

  • synchronized 锁的对象是方法的调用者
  • 两个方法用的是同一个锁,谁先拿到谁执行
  • 普通的方法是用对象操作的(同步方法 对象)
  • static静态方法是用Class操作的(静态同步方法 Class)
  • new this 具体的一个手机
  • static Class 唯一的一个模板

八种情况:
两个同步方法,一个对象(发短信,打电话)
两个同步方法,一个对象,发短信延迟(发短信,打电话)
一个同步方法,一个普通方法,一个对象,同步方法延迟(打电话,发短信)
两个同步方法,两个对象,发短信延迟(打电话,发短信)
两个静态同步方法,一个对象,发短信延迟(发短信,打电话)
两个静态同步方法,两个对象,发短信延迟(发短信,打电话)
一个静态同步方法,一个普通同步方法,一个对象,静态同步方法延迟(打电话,发短信)
一个普通同步方法,一个静态同步方法,两个对象,静态同步方法延迟(打电话,发短信)

二、代码案例

1、案例1

package com.sgz.lock8;

import java.util.concurrent.TimeUnit;

/**
 * 日期:2022/8/30 - 10:34
 * 需求:两个同步方法,一个对象(发短信,打电话)
 */
public class Lock01 {
    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() {
        System.out.println("发短信");
    }

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

2、案例2

package com.sgz.lock8;

import java.util.concurrent.TimeUnit;

/**
 * 日期:2022/8/30 - 10:34
 * 需求:两个同步方法,一个对象,发短信延迟(发短信,打电话)
 */
public class Lock02 {
    public static void main(String[] args) {

        Phone2 phone = new Phone2();

        // 锁的存在
        new Thread(() -> {
            phone.sendSms();
        }, "A").start();

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

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

class Phone2 {

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

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

3、案例3

package com.sgz.lock8;

import java.util.concurrent.TimeUnit;

/**
 * 日期:2022/8/30 - 10:34
 * 需求:一个同步方法,一个普通方法,一个对象,同步方法延迟(hello,发短信)
 */
public class Lock03 {
    public static void main(String[] args) {

        Phone3 phone = new Phone3();

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

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

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

class Phone3 {

    public synchronized void sendSms() {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    // 没有锁,不是同步方法,不受锁的影响
    public  void call() {
        System.out.println("打电话");
    }
}

4、案例4

package com.sgz.lock8;

import java.util.concurrent.TimeUnit;

/**
 * 日期:2022/8/30 - 10:34
 * 需求:两个同步方法,两个对象,发短信延迟(打电话,发短信)
 */
public class Lock04 {
    public static void main(String[] args) {

        // 两个对象,两个调用者,两把锁,与时间无关
        Phone4 phone1 = new Phone4();
        Phone4 phone2 = new Phone4();

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

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

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

class Phone4 {

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

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

5、案例5

package com.sgz.lock8;

import java.util.concurrent.TimeUnit;

/**
 * 日期:2022/8/30 - 10:34
 * 需求:两个静态同步方法,一个对象,发短信延迟(发短信,打电话)
 */
public class Lock05 {
    public static void main(String[] args) {

        Phone5 phone = new Phone5();

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

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

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

class Phone5 {

    // static 静态方法
    // 类一加载就有了,锁的是Class
    public static synchronized void sendSms() {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

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

6、案例6

package com.sgz.lock8;

import java.util.concurrent.TimeUnit;

/**
 * 日期:2022/8/30 - 10:34
 * 需求:两个静态同步方法,两个对象,发短信延迟(发短信,打电话)
 */
public class Lock06 {
    public static void main(String[] args) {

        // 两个对象的Class类模板只有一个,static,锁的是Class类Phone6
        Phone6 phone1 = new Phone6();
        Phone6 phone2 = new Phone6();

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

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

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

// Phone6 唯一的一个 Class 对象
class Phone6 {

    // static 静态方法
    // 类一加载就有了,锁的是Class
    public static synchronized void sendSms() {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

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

7、案例7

package com.sgz.lock8;

import java.util.concurrent.TimeUnit;

/**
 * 日期:2022/8/30 - 10:34
 * 需求:一个静态同步方法,一个普通同步方法,一个对象,静态同步方法延迟(打电话,发短信)
 */
public class Lock07 {
    public static void main(String[] args) {

        Phone7 phone = new Phone7();

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

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

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

class Phone7 {

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

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

8、案例8

package com.sgz.lock8;

import java.util.concurrent.TimeUnit;

/**
 * 日期:2022/8/30 - 10:34
 * 需求:一个普通同步方法,一个静态同步方法,两个对象,静态同步方法延迟(打电话,发短信)
 */
public class Lock08 {
    public static void main(String[] args) {

        // 两个对象的Class类模板只有一个,static,锁的是Class类Phone6
        Phone8 phone1 = new Phone8();
        Phone8 phone2 = new Phone8();

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

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

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

class Phone8 {

    // static 静态方法
    // 类一加载就有了,锁的是Class
    public static synchronized void sendSms() {
        try {
            TimeUnit.SECONDS.sleep(3);
        } 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、付费专栏及课程。

余额充值