JUC多线程八锁问题

1. 两个同步方法,一个对象调用,中间延时1毫秒,先发短信还是先打电话? 结果:发短信

  • synchronized 修饰普通方法锁的是对象;
  • 两个方法是同一把对象锁,发短信先拿到锁,所以先发短信,并不是因为执行顺序和延时导致的打电话比较晚;
import java.util.concurrent.TimeUnit;

public class EightLock {
    public static void main(String[] args) {
        Phone phone = new Phone();
        
        // 发短信 ()->{} lambda 表达式,JDK8 新特性,作用等同于匿名接口实现类
        /*  
            new Thread(new Runnable() {
                @Override
                public void run() {
                    phone.send();
                }
            }).start();
        */
        new Thread(()->{
            phone.send();
        }).start();
        
        try {
            // 延时 1 ms
            TimeUnit.MILLISECONDS.sleep(1);
        } catch (Exception e) {}

        // 打电话
        new Thread(()->{
            phone.call();
        }).start();
    }
}

/** 手机类 */
class Phone {
    public synchronized void send() {
        System.out.println("发短信");
    }

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

/*
    发短信
    打电话
*/

2. 两个同步方法,一个对象调用,先发短信还是先打电话? 结果:发短信

  • 两个方法是同一把对象锁,谁先拿到就先执行,即便有sleep(),也抱着锁睡觉 ,打电话需要等待发短信完成;
import java.util.concurrent.TimeUnit;

public class EightLock {
    public static void main(String[] args) {
        Phone phone = new Phone();
        
        // 发短信
        new Thread(()->{
            phone.send();
        }).start();

        // 打电话
        new Thread(()->{
            phone.call();
        }).start();
    }
}

/** 手机类 */
class Phone {
    public synchronized void send() {
        try {
            // 延时 3 ms
            TimeUnit.MILLISECONDS.sleep(3);
        } catch (Exception e) {}
        System.out.println("发短信");
    }

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

/*
    发短信
    打电话
*/

3. 一个同步方法,一个普通方法,一个对象调用,先发短信还是打电话? 结果:打电话

  • 普通方法没有锁,不需要获取锁,打电话不用等待;
package com.simple.juc;

import java.util.concurrent.TimeUnit;

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

        // 发短信
        new Thread(()->{
            phone.send();
        }).start();

        // 打电话
        new Thread(()->{
            phone.call();
        }).start();
    }
}

/** 手机类 */
class Phone {
    public synchronized void send() {
        try {
            // 延时 3 ms
            TimeUnit.MILLISECONDS.sleep(3);
        } catch (Exception e) {}
        System.out.println("发短信");
    }

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

/*
    打电话
    发短信
*/

4. 两个同步方法,两个对象调用,先发短信还是打电话? 结果:打电话

  • 两个方法是两把不同的对象锁,互不影响,打电话不用等待;
import java.util.concurrent.TimeUnit;

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

        // 发短信
        new Thread(()->{
            phone1.send();
        }).start();

        // 打电话
        new Thread(()->{
            phone2.call();
        }).start();
    }
}

/** 手机类 */
class Phone {
    public synchronized void send() {
        try {
            // 延时 3 ms
            TimeUnit.MILLISECONDS.sleep(3);
        } catch (Exception e) {}
        System.out.println("发短信");
    }

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

/*
    打电话
    发短信
*/

5. 两个静态同步方法,一个对象调用,先发短信还是打电话? 结果:发短信

  • synchronized 修饰静态方法锁class类模板;
  • 两个方法是同一把类锁,发短信先拿类锁,打电话需要等待;
import java.util.concurrent.TimeUnit;

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

        // 发短信
        new Thread(()->{
            phone.send();
        }).start();

        // 打电话
        new Thread(()->{
            phone.call();
        }).start();
    }
}

/** 手机类 */
class Phone {
    public static synchronized void send() {
        try {
            // 延时 3 ms
            TimeUnit.MILLISECONDS.sleep(3);
        } catch (Exception e) {}
        System.out.println("发短信");
    }

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

/*
    发短信
    打电话
*/

6. 两个静态同步方法,两个对象调用,先发短信还是打电话? 结果:发短信

  • 两个方法是同一把类锁,虽然对象不同,但是同一个类,需要同一把锁,打电话需要等待;
import java.util.concurrent.TimeUnit;

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

        // 发短信
        new Thread(()->{
            phone1.send();
        }).start();

        // 打电话
        new Thread(()->{
            phone2.call();
        }).start();
    }
}

/** 手机类 */
class Phone {
    public static synchronized void send() {
        try {
            // 延时 3 ms
            TimeUnit.MILLISECONDS.sleep(3);
        } catch (Exception e) {}
        System.out.println("发短信");
    }

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

/*
    发短信
    打电话
*/

7. 一个静态同步方法,一个同步方法,一个对象调用,先发短信还是打电话? 结果:打电话

  • 两个方法是两把不同的锁,一个是类锁,一个是对象锁,互不影响,打电话不用等待;
import java.util.concurrent.TimeUnit;

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

        // 发短信
        new Thread(()->{
            phone.send();
        }).start();

        // 打电话
        new Thread(()->{
            phone.call();
        }).start();
    }
}

/** 手机类 */
class Phone {
    public static synchronized void send() {
        try {
            // 延时 3 ms
            TimeUnit.MILLISECONDS.sleep(3);
        } catch (Exception e) {}
        System.out.println("发短信");
    }

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

/*
    打电话
    发短信
*/

8. 一个静态同步方法,一个同步方法,两个对象调用,先发短信还是打电话? 结果:打电话

  • 两个方法是两把不同的锁,一个是类锁,一个是对象锁,互不影响;
import java.util.concurrent.TimeUnit;

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

        // 发短信
        new Thread(()->{
            phone1.send();
        }).start();

        // 打电话
        new Thread(()->{
            phone2.call();
        }).start();
    }
}

/** 手机类 */
class Phone {
    public static synchronized void send() {
        try {
            // 延时 3 ms
            TimeUnit.MILLISECONDS.sleep(3);
        } catch (Exception e) {}
        System.out.println("发短信");
    }

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

/*
    打电话
    发短信
*/
posted @ 2022-03-05 21:36  a最简单  阅读(43)  评论(0编辑  收藏  举报