JUC_8Lock

80 阅读3分钟

关于8锁需要弄明白的就是锁的是谁,其他线程能不能抢占到锁?

1.1-2锁

  1. 标准访问有ab两个线程,请问先打印邮件还是短信?
  2. sendEmail 方法中加入暂停3s 请问是先打印邮件还是短信?
package com.sol.lock_8;
import java.util.concurrent.TimeUnit;

/**
 * 1.标志情况下,两个线程先打印,发短信? 打电话?
 * 2.sendSms延迟4秒,两个线程先打印,发短信? 打电话?
 */
public class Lock_1To2 {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();

        //发短信
        new Thread(()->{
            try {
                phone.sendSms();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"发短信").start();

        //延时
        TimeUnit.SECONDS.sleep(1);

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

class Phone{

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

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

结论 :一个对象里面如果有多个synchronized方法,某一时刻内只能有一个线程去访问这些synchronized方法,锁的是当前对象this,被锁定后,其他线程都不能进入到当前对象的其他synchronized方法

2.3-4锁

  1. 有一部手机 一个普通的hello方法,一个睡眠3s邮件方法,请问先打印邮件还是 hello方法
  2. 有两部手机,一个普通的hello方法,一个睡眠3s邮件方法,请问先打印邮件还是 hello方法
package com.sol.lock_8;
import java.util.concurrent.TimeUnit;

/**
 * 3.静态方法,普通方法  打电话?发短信?
 * 4.不同对象         打电话?发短信?
 */
public class Lock_3To4 {
    public static void main(String[] args) throws InterruptedException {
        Phone2 phone2 = new Phone2();
        Phone2 phone3 = new Phone2();

        //发短信
        new Thread(()->{
            try {
                phone2.sendSms();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"发短信").start();

        //延时
        TimeUnit.SECONDS.sleep(1);

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

    }
}

class Phone2{

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

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

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

结论 :1.普通方法与同步锁无关直接执行
2.换成两个对象不是同一把锁,各锁各的this 对象锁

3.5-6锁

  1. 静态同步方法,同一对象,发短信? 打电话?
  2. 静态同步方法,不同对象,两个线程先打印,发短信? 打电话?
package com.sol.lock_8;


import java.util.concurrent.TimeUnit;

/**
 * 5.静态同步方法,同一对象,发短信? 打电话?
 * 6.静态同步方法,不同对象,两个线程先打印,发短信? 打电话?
 */
public class Lock_5To6 {
    public static void main(String[] args) throws InterruptedException {
        Phone3 phone1 = new Phone3();
        Phone3 phone2 = new Phone3();

        //发短信
        new Thread(()->{
            try {
                phone1.sendSms();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"发短信").start();

        //延时
        TimeUnit.SECONDS.sleep(1);

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

    }
}

class Phone3{

    //类一加载就有了!锁的是Class
    //synchronized 锁的对象是方法的调用者
    //两个方法使用的是同一个锁,哪个先拿到哪个先执行
    public static synchronized void sendSms() throws InterruptedException {
        TimeUnit.SECONDS.sleep(3);
        System.out.println("发短信");
    }

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

}

结论 :对于静态同步方法锁的是当前类的Class对象,同一把类锁

4.7-8锁

  1. 静态同步方法和同步方法,有1部手机,请问先打印邮件还是短信?
  2. 静态同步方法和同步方法,有2部手机,清问先打印邮件还是短信?
package com.sol.lock_8;

/**
 * 7.静态同步方法和同步方法 ,同一对象  发短信?打电话?
 * 8.静态同步方法和同步方法 ,不同对象  发短信?打电话?
 */

import java.util.concurrent.TimeUnit;


public class Lock_7To8 {
    public static void main(String[] args) throws InterruptedException {
        Phone4 phone1 = new Phone4();
        Phone4 phone2 = new Phone4();

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

        //延时
        TimeUnit.SECONDS.sleep(1);

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

    }
}

class Phone4{

      //不同的锁,谁先拿到谁执行
    public static synchronized void sendSms() {
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("发短信");
    }

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

}
> 结论 :静态同步方法和同步方法 一个锁的Class 一个锁的this 不同的锁,谁先拿到谁执行