JUC并发编程(二)-- 线程八锁


线程八锁,指的就是线程中关于锁的八个问题,用来分辨清晰Java多线程中,锁究竟锁的是什么。
以下 5 和 6 两个问题分别是两个子问题的综合,一共八个问题。
:下面的所有问题中,A和B两个线程,分别按顺序在main() 中创建。也就是A先拿到锁。

1、两个线程,分别调用同一个资源类的两个方法,哪个先执行?
2、两个线程A和B,分别调用同一个资源类的两个方法,A线程休眠3秒,哪个线程先执行?

回答:谁先拿到锁谁先执行。
原因:锁是锁的方法的调用者。
代码实例
资源类:

package com.zhan.juc.lockBy8question;

import java.util.concurrent.TimeUnit;

/**
 * @Author Zhanzhan
 * @Date 2020/11/28 15:43
 * 资源类
 */
public class Data {

    public synchronized void printA(){
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("执行线程A");
    }

    public synchronized void printB(){
        System.out.println("执行线程B");
    }
}

线程操作类:

package com.zhan.juc.lockBy8question;

import java.util.concurrent.TimeUnit;

/**
 * @Author Zhanzhan
 * @Date 2020/11/28 15:42
 * 锁的八个问题--第一个
 * 两个线程,分别调用同一个资源类的两个方法,哪个先执行?
 */
public class Question1 {
    public static void main(String[]args) throws InterruptedException {
        Data data = new Data();

        //
        new Thread(()->{
            data.printA();
        }, "A").start();

        TimeUnit.SECONDS.sleep(1);

        new Thread(()->{
            data.printB();
        },"B").start();
    }
}

运行结果如下:
在这里插入图片描述

3、非同步方法是否会受到对象锁的影响?

问题详述:两个线程A和B,分别调用同一个资源类里的方法,其中A线程调用的是同步方法,B线程调用的是普通方法,其中A线程调用的同步方法休眠3秒,问,哪个线程先执行?
回答:B线程先执行。
原因:非同步方法不会受到对象锁的影响。
代码实例:
资源类:

package com.zhan.juc.lockBy8question;

import java.util.concurrent.TimeUnit;

/**
 * @Author Zhanzhan
 * @Date 2020/11/28 15:43
 * 资源类
 */
public class Data {

    public synchronized void printA(){
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("执行线程A");
    }

    public synchronized void printB(){
        System.out.println("执行线程B");
    }

    public void hello(){
        System.out.println("hello");
    }
}

线程操作类:

package com.zhan.juc.lockBy8question;

import java.util.concurrent.TimeUnit;

/**
 * @Author Zhanzhan
 * @Date 2020/11/28 20:35
 * 锁的八个问题--第三个
 * 非同步方法是否会受到对象锁的影响
 */
public class Question3 {
    public static void main(String[]args) throws InterruptedException {
        Data data = new Data();

        // 这里的线程A调用的是data对象的同步方法
        new Thread(()->{
            data.printA();
        }, "A").start();

        TimeUnit.SECONDS.sleep(1);

        // 这里的线程B调用的是data对象的非同步方法
        new Thread(()->{
            data.hello();
        },"B").start();
    }
}

运行结果如下:
在这里插入图片描述

4、同一个类中两个对象的同步方法时候会相互影响?

问题描述:线程A调用 Data 类的 对象data1的同步方法a(),其中a() 中会休眠3秒,线程B调用 Data 类的 对象 data2 的同步方法b(),谁先执行?
回答:线程B先执行。
原因:同一个类的两个对象的同步方法不会互相影响。
代码实例
资源类:

package com.zhan.juc.lockBy8question;

import java.util.concurrent.TimeUnit;

/**
 * @Author Zhanzhan
 * @Date 2020/11/28 15:43
 * 资源类
 */
public class Data {

    public synchronized void printA(){
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("执行线程A");
    }

    public synchronized void printB(){
        System.out.println("执行线程B");
    }

    public void hello(){
        System.out.println("hello");
    }
}

线程操作类:

package com.zhan.juc.lockBy8question;

import java.util.concurrent.TimeUnit;

/**
 * @Author Zhanzhan
 * @Date 2020/11/28 20:40
 * 锁的八个问题--第四个
 * 两个线程 A 和 B ,分别调用同一个资源类的 两个 对象的同步方法, 是否会互相影响
 */
public class Question4 {
    public static void main(String[] args) throws InterruptedException {
        Data data1 = new Data();
        Data data2 = new Data();

        new Thread(() -> {
            data1.printA();
        }, "A").start();

        TimeUnit.SECONDS.sleep(1);

        new Thread(() -> {
            data2.printB();
        }, "B").start();
    }
}

运行结果如下:
在这里插入图片描述

5、同一个类中的两个静态同步方法时候会互相影响?

问题描述:同一个资源类中,设置两个静态的同步方法a() 和 b(),然后用线程A调用a(),线程B调用b(),其中a() 中休眠3秒,问,哪个线程先执行?
回答:线程A先执行。
原因:静态同步方法,锁的是整个class,所以这两个静态的同步方法会互相影响。
代码实例

package com.zhan.juc.lockBy8question;

import java.util.concurrent.TimeUnit;

/**
 * @Author Zhanzhan
 * @Date 2020/11/28 20:54
 * 锁的八个问题--第四个
 * 同一个资源类中,设置两个静态的同步方法a() 和 b(),然后用线程A调用a(),线程B调用b(),其中a() 中休眠3秒,问,哪个线程先执行
 */
public class Question5 {
    public static void main(String[]args) throws InterruptedException {

        new Thread(()->{
            Data5.printA();
        },"A").start();

        TimeUnit.SECONDS.sleep(1);

        new Thread(()->{
            Data5.printB();
        },"B").start();
    }
}

/**
 * 资源类,里面有两个静态同步方法
 */
class Data5{
    public static synchronized void printA(){
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("执行线程A");
    }

    public static synchronized void printB(){
        System.out.println("执行线程B");
    }
}

运行结果如下:
在这里插入图片描述

6、同一个类中,一个静态同步方法和一个普通同步方法,会相互影响吗?

问题描述:同一个资源类中,有一个静态同步方法 a(),和一个普通同步方法 b(),然后用线程A调用a(),线程B调用b(),其中a() 中休眠3秒,问,哪个线程先执行?
回答:线程B先执行。
原因:静态同步方法的锁,锁的是当前的Class对象;普通同步方法的锁,锁的是当前new 出来的对象。两个锁不是锁的同一个东西。
代码实例

package com.zhan.juc.lockBy8question;

import java.util.concurrent.TimeUnit;

/**
 * @Author Zhanzhan
 * @Date 2020/11/28 22:09
 * 线程八锁
 * 同一个资源类中,有一个静态同步方法 a(),和一个普通同步方法 b(),然后用线程A调用a(),线程B调用b(),其中a() 中休眠3秒,哪个线程先执行?
 */
public class Question6 {
    public static void main(String[] args) throws InterruptedException {
        Data6 data = new Data6();

        new Thread(Data6::printA, "A").start();

        TimeUnit.SECONDS.sleep(1);

        new Thread(()->{
            data.printB();
        }, "B").start();
    }
}

class Data6{

    /**
     * 这里锁的是当前的Class对象
     */
    public static synchronized void printA(){
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("执行线程A");
    }

    /**
     * 这里锁的是当前的调用者对象,即 new 出来的对象
     */
    public synchronized void printB(){
        System.out.println("执行线程B");
    }
}

运行结果如下:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值