JUC并发编程 -- 方法上的synchronized(同步方法) & 线程八锁

Posted Z && Y

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JUC并发编程 -- 方法上的synchronized(同步方法) & 线程八锁相关的知识,希望对你有一定的参考价值。

避免临界区的竞态条件之synchronized 解决方案

1. 方法上的 synchronized

把synchronized加在成员方法上:

锁住的是this对象


把synchronized加在静态方法上:

锁住的是类对象


2. 线程八锁


2.1 情况1

情况1:

import lombok.extern.slf4j.Slf4j;

@Slf4j(topic = "c.Test18")
public class Test18 {
    public static void main(String[] args) {
        Number n1 = new Number();
        new Thread(() -> {
            n1.a();
        }).start();
        new Thread(() -> {
            n1.b();
        }).start();
    }
}

@Slf4j(topic = "c.Number")
class Number {
    public synchronized void a() {
        log.debug("1");
    }

    public synchronized void b() {
        log.debug("2");
    }
}

情况1运行结果: 12 或 21 (看CPU先调度哪个线程,因为第一个线程先启动,所以线程1被CPU调度的机会大一些,12的情况就多一些)


2.2 情况2

情况2:

情况2运行结果: :1s 后1 2,或 2 1s后 1(看CPU先调度哪个线程,因为第一个线程先启动,所以线程1被CPU调度的机会大一些,1s 后1 2的情况就多一些)

情况2完整代码:


2.3 情况3

情况3:


情况3运行结果: :3 1s 12 或 23 1s 1 或 32 1s 1(c方法调用的时候不会出现互斥的情况,a和b方法调用时会出现互斥的现象:因为锁的是同一个对象。)

情况3完整代码:


2.4 情况4

情况4:

情况4运行结果: :2 1s 后 1(因为锁住的不是同一个对象,所以不会发生互斥的现象)

情况4完整代码:


2.5 情况5

情况5:


情况5运行结果: :2 1s 后 1(因为锁住的不是同一个对象(一个锁住的类对象,一个锁住的实例对象),所以不会发生互斥的现象)

情况5完整代码:


2.6 情况6

情况6:

情况6运行结果: :1s 后1 2,或 2 1s后 1(看CPU先调度哪个线程,因为第一个线程先启动,所以线程1被CPU调度的机会大一些,1s 后1 2的情况就多一些。因为锁住的都是类对象,类对象在内存中只有一个,所以会发生互斥现象。)

情况6完整代码:


2.7 情况7

情况7:


情况7运行结果: 2 1s 后 1(因为锁住的是不同对象,所以不会发生互斥的情况。)

情况7完整代码:


2.8 情况8

情况8:

情况8运行结果1s 后12, 或 2 1s后 1(因为锁住的都是类对象,所以会发生互斥现象):

情况8完整代码:



以上是关于JUC并发编程 -- 方法上的synchronized(同步方法) & 线程八锁的主要内容,如果未能解决你的问题,请参考以下文章

尚硅谷JUC高并发编程学习笔记JUC简介与Lock接口

尚硅谷JUC高并发编程学习笔记JUC简介与Lock接口

JUC并发编程 共享模式之工具 JUC 线程安全的集合类 -- 线程安全的集合类概述

JUC并发编程 -- 线程状态转换

JUC并发编程 -- 线程常用方法概述 & start() vs run()

JUC并发编程 -- 观察线程运行的现象 & 查看进程线程的方法