Java JUC并发之关于锁的八个问题

五、8 锁问题

如何判断锁的是谁?

对象 、Class

深入理解 锁

package com.liu.lock8;

import java.util.concurrent.TimeUnit;

/**
 * 8锁 : 关于锁的八个问题
 *   1. 标准情况下,两个线程先打印 发短信 还是 打电话 ? 1 发短信!
 *   2. sendMessage 延迟4s下 ,还是先发短信
 */
public class Test1 {

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

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


        // 延时1s
        try {
            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone.call();
        },"B").start();
    }
}
class Phone{ // 资源类

    // synchronized 锁的是方法的调用对象

    // 两个方法用的是同一个锁 谁先拿到谁执行
    public synchronized void sendMessage() { // 发短信


        // 延时1s
        try {
            TimeUnit.MILLISECONDS.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("发送消息!!");
    }
    public synchronized void call() { // 打电话

        System.out.println("打电话!!");

    }

    public void hello() { // hello方法没有加同步锁 不是同步方法,不受锁的影响
        System.out.println("Hello!");
    }
}
package com.liu.lock8;

import java.util.concurrent.TimeUnit;

/**
 * 8锁 : 关于锁的八个问题
 *   3. 编写了一个普通方法,由线程B调用 此时先打印? Hello => 普通方法不受影响
 *   4. 创建两个对象,两个调用者 => 两把锁
 */
public class Test2 {

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

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


        // 延时1s
        try {
            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone2.call();
        },"B").start();
    }
}
class Phone2{ // 资源类

    // synchronized 锁的是方法的调用对象

    // 两个方法用的是同一个锁 谁先拿到谁执行
    public synchronized void sendMessage() { // 发短信


        // 延时4s
        try {
            TimeUnit.MILLISECONDS.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("发送消息!!");
    }
    public synchronized void call() { // 打电话

        System.out.println("打电话!!");

    }

    public void hello() { // hello方法没有加同步锁 不是同步方法,不受锁的影响
        System.out.println("Hello!");
    }
}
package com.liu.lock8;
/**
 * 5. 增加两个静态的同步方法 锁的是类Class 模板  先打印发短信
 * 6. 两个对象,并且增加两个静态的同步方法?  先打印发短信
 */

import java.util.concurrent.TimeUnit;

public class Test3 {
    public static void main(String[] args) {

        // 两个对象的Class 模板只有一个!加了static => 锁的是Class
        Phone3 phone = new Phone3();
        Phone3 phone2 = new Phone3();

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


        // 延时1s
        try {
            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone.call();
        },"B").start();
    }
}
class Phone3{ // 资源类

    // synchronized 锁的是方法的调用对象
    // static静态方法
    // 类一加载就有了! Class模板 锁的是Class

    public static synchronized void sendMessage() { // 发短信


        // 延时4s
        try {
            TimeUnit.MILLISECONDS.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("发送消息!!");
    }
    public static synchronized void call() { // 打电话

        System.out.println("打电话!!");

    }

    public void hello() { // hello方法没有加同步锁 不是同步方法,不受锁的影响
        System.out.println("Hello!");
    }
}
package com.liu.lock8;

import java.util.concurrent.TimeUnit;

/**
 * 7. 一个静态同步方法、一个普通同步方法 ,只有一个对象  先打印 打电话
 * 8. 一个静态同步方法、一个普通同步方法 ,有两个对象  先打印 打电话
 */
public class Test4 {
    public static void main(String[] args) {

        // 两个对象的Class 模板只有一个!加了static => 锁的是Class
        Phone4 phone = new Phone4();
        Phone4 phone2 = new Phone4();

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


        // 延时1s
        try {
            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone2.call();
        },"B").start();
    }
}
class Phone4{ // 资源类

    // synchronized 锁的是方法的调用对象
    // static静态方法
    // 类一加载就有了! Class模板 锁的是Class



    //静态的同步方法 锁的是Class
    public static synchronized void sendMessage() { // 发短信


        // 延时4s
        try {
            TimeUnit.MILLISECONDS.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("发送消息!!");
    }

    // 普通同步方法 锁的是调用者
    public synchronized void call() { // 打电话

        System.out.println("打电话!!");

    }

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

总结

new this 关键字 => 对象锁 具体的 实例 方法的调用对象 多个对象对应多把锁

static 关键字 => 类锁 Class 唯一的一个模板 只有一把锁

posted @ 2021-07-15 16:43  夕立君  阅读(53)  评论(0编辑  收藏  举报