首页 > 其他分享 >多线程六-线程通信之Condition使用与设计猜想

多线程六-线程通信之Condition使用与设计猜想

时间:2024-09-16 11:03:07浏览次数:8  
标签:lock concurrent 线程 Condition import 多线程 condition

海上生明月,天涯共此时。愿大家在这个团圆的夜晚,收获满满的温馨和喜悦,团圆美满,中秋快乐!
月满中秋

使用示例

ConditionDemoAwait :开始之后加锁,阻塞并释放锁

package com.caozz.demo5.concurrent;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

public class ConditionDemoAwait implements Runnable{

    private Lock lock;

    private Condition condition;

    public ConditionDemoAwait(Lock lock, Condition condition){
        this.condition = condition;
        this.lock = lock;
    }

    @Override
    public void run() {
        System.out.println("begin---ConditoiopnDemoAwait--");
        lock.lock();
        try{
            condition.await();
            System.out.println("end---ConditoiopnDemoAwait--");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

  • ConditionDemoSinal :开始之后唤醒,此时并不会释放锁,所以会先结束,才会释放锁
package com.caozz.demo5.concurrent;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

public class ConditionDemoSinal implements Runnable{

    private Lock lock;

    private Condition condition;

    public ConditionDemoSinal(Lock lock, Condition condition){
        this.condition = condition;
        this.lock = lock;
    }

    @Override
    public void run() {
        System.out.println("begin---ConditoiopnDemoSinal--");
        lock.lock();
        try{
            //让当前线程阻塞,相当于Object.notify()
            condition.signal();
            System.out.println("end---ConditoiopnDemoSinal--");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

测试:

package com.caozz.demo5.controller;

import com.caozz.demo5.concurrent.ConditionDemoAwait;
import com.caozz.demo5.concurrent.ConditionDemoSinal;
import com.caozz.demo5.concurrent.Consumer;
import com.caozz.demo5.concurrent.Producer;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Test {
    public static void main(String[] args) throws InterruptedException {
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
        ConditionDemoAwait await = new ConditionDemoAwait(lock, condition);
        ConditionDemoSinal sinal = new ConditionDemoSinal(lock, condition);
        new Thread(await).start();
        Thread.sleep(10);
        new Thread(sinal).start();
    }
}

结果:
线程启动:await启动,执行开始后加锁,并阻塞,此时signal开始,并执行唤醒,然后signal结束,释放锁,被唤醒得await结束
如果启动不加sleep,可能会sinal先启动,那么sinal开始,唤醒,结束,然后await执行,阻塞,然后就会一直阻塞,无法结束,因为没有被唤醒

begin---ConditoiopnDemoAwait--
begin---ConditoiopnDemoSinal--
end---ConditoiopnDemoSinal--
end---ConditoiopnDemoAwait--

设计猜想

  • 作用:实现线程的阻塞与唤醒
  • 前提条件: 必须先要获得锁
  • await、signal、signalall
    • await:让线程阻塞,并且释放锁
    • signal:唤醒阻塞的线程

  • 加锁的操作,必然会涉及到AQS的阻塞队列
  • await释放锁时,AQS队列中不存在已经释放锁的线程,那么被释放的线程去到了哪里?
  • 唤醒被阻塞的线程:被阻塞的线程在哪里?
    经过上面的思考,应该可以想到,通过await方法释放的线程,必须要有一个地方来存储,同时,阻塞的线程,是通过AQS还是单独地方来存储呢?

Condition等价于wait/notify
Condition是JUC里面得实现,所以不能使用wait/notify ,锁的实现不同。

欢迎大家留言,以便于后面的人更快解决问题!另外亦欢迎大家可以关注我的微信公众号,方便利用零碎时间互相交流。共勉!

标签:lock,concurrent,线程,Condition,import,多线程,condition
From: https://www.cnblogs.com/caozz/p/18416083/thread-condition-desigh

相关文章

  • Android HandlerThread Post后延迟7秒才执行的原因及解决方案|如何提高Android后台线程
    在Android开发中,HandlerThread是用于处理后台线程任务的常见工具。然而,有时我们会遇到这样的问题:当任务通过HandlerThread的post方法发送后,任务的执行时间会出现明显的延迟,比如7秒的延迟才执行任务。本文将深入分析这种问题的成因,探讨可能的影响因素,并提供多种优化方案,帮助开发者解......
  • 多线程五-线程通信之wait与notify
    wait与notify用于syncronized的线程间通信的一种,wait用来阻塞线程并释放锁,notify用来唤醒线程。他们与condition作用基本一致,但是由于syncronized为jdk实现,阅读源码有难度,所以通过了解其原理,用来帮助我们后续理解condition的源码。可以通过下面一张图来理解:下面通过一个简单的......
  • [Java并发]守护线程
    守护线程和普通线程的最大区别是守护线程会在主线程结束后退出,但是普通线程在主线程结束后不会退出。普通线程的执行importjava.sql.Time;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;publicclassMain{publicstaticvoid......
  • Python 课程8-多线程编程和多进程编程
    前言        在现代编程中,处理并发任务是提高程序性能的关键之一。Python提供了多线程(threading)和多进程(multiprocessing)两种方式来实现并发编程。多线程适用于I/O密集型任务,而多进程则更适合CPU密集型任务。通过这两种技术,你可以高效地处理大规模数据、加速......
  • 浅谈线程的创建方式
    引言在网上查询这个问题,大多回答是线程的创建方式有四种。继承Thread类实现Runnable接口实现Callable接口使用线程池但是这种说法是错误的,或者说是不正确的不严谨的。我的想法实际上,在Java中创建线程的方式只有一种,就是使用newThread()只有这样才能创建一个线......
  • 多线程篇(面试题)(持续更新迭代)
    目录文档说明一、线程的基础知识1.线程和进程的区别?2.并行和并发有什么区别?3.创建线程的四种方式4.runnable和callable有什么区别5.线程的run()和start()有什么区别?6.线程包括哪些状态,状态之间是如何变化的7.新建T1、T2、T3三个线程,如何保证它们按顺序......
  • C++实现线程池
    目录一.什么是线程池二.为什么要用线程池三.如何实现线程池这篇文章简单讨论下线程池。一.什么是线程池线程池简单来时就是维护了一组线程的池子,这组线程执行一些相似任务。是一种线程的使用方式。二.为什么要用线程池有的时候系统需要处理大量相似任务,频繁创建销......
  • Java HashMap详解:源码分析、hash 原理、扩容机制、加载因子、线程不安全
    这篇文章将会详细透彻地讲清楚Java的HashMap,包括hash方法的原理、HashMap的扩容机制、HashMap的加载因子为什么是0.75而不是0.6、0.8,以及HashMap为什么是线程不安全的,基本上HashMap的常见面试题,都会在这一篇文章里讲明白。HashMap是Java中常用的数据结构之一......
  • modbus调试助手/mqtt调试工具/超轻巧物联网组件/多线程实时采集/各种协议支持
    一、前言说明搞物联网开发很多年,用的最多的当属modbus协议,一个稳定好用的物联网组件是物联网平台持续运行多年的基石,所以这个物联网组件从一开始就定位于自研,为了满足各种场景的需求,当然最重要的一点就是大大提升了自己对该协议的深度理解和应用,尤其是面对各种场景需求,逐步调整迭......
  • springboot动态线程池
    1、配置文件新增每个线程池的基本参数配置thread-pool.user-thread.corePoolSize=1thread-pool.user-thread.maxPoolSize=1thread-pool.user-thread.keepAliveSeconds=120thread-pool.user-thread.queueCapacity=1thread-pool.school-thread.corePoolSize=2thread-pool.sch......