不要玄之又玄:多线程相关知识点的通俗理解

Java实现多线程内容通俗易懂,一篇文章了解多线程并且能到简单的使用多线程 本篇文章涉及的内容为多线程的基础内容讲解,全是基础内容,必须的掌握 阅读详情

线程和进程的区别

  • 进程是一个程序执行一次创建的,是系统运行程序的基本单位。
  • 线程是⼀个⽐进程更⼩的执⾏单位,一个进程在运行期间可以产生多个线程。多个线程可以共享进程的堆和⽅法区资源,每个线程有⾃⼰的程序计数器、虚拟机栈和本地⽅法栈。
  • 线程是进程划分成的更⼩的运⾏单位。
  • 线程和进程最⼤的不同在于基本上各进程是独⽴的,⽽各线程则可以有共享的资源也有自己独有的资源。
  • 线程执⾏开销⼩,但不利于资源的管理和保护;⽽进程正相反

线程的三大特性

  • 原子性
  • 可见性
  • 有序性

在java中,lock、synchronized能够实现三个特性,volatile只能实现可见性和有序性

synchronized的实现和升级过程

从JDK1.6之前使用monitor对象实现线程互斥,在1.6时完成优化,通过偏向锁-轻量锁-重量锁的升级来平衡功能和性能。
参考

synchronized的缺点

  • synchronized 在已经获取了锁A的情况下去获取锁B,如果锁B获取不到,它不会释放锁A(请求和保持)
  • synchronized 获取锁B时获取不到时会进入阻塞状态,啥也干不了,也不能被中断/打断,也就无法去释放已获得的资源(不可剥夺)

这也是我们发生死锁时的两个条件:1,保持和等待;2,不可被剥夺/抢占

unsafe

Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,这些方法在提升Java运行效率、增强Java语言底层资源操作能力方面起到了很大的作用。但由于Unsafe类使Java语言拥有了类似C语言指针一样操作内存空间的能力,这无疑也增加了程序发生相关指针问题的风险。在程序中过度、不正确使用Unsafe类会使得程序出错的概率变大,使得Java这种安全的语言变得不再“安全”,因此对Unsafe的使用一定要慎重。
在这里插入图片描述

多线程的几个对象

  • 任务对象

    • Runable
      • 核心方法run方法
      • 需要通过线程池executor的execute方法执行
    • Callable:
      • 核心方法 call方法
      • 需要通过线程池executor的submit方法执行
  • 执行对象

    • executor:顶层接口,包含execute方法
    • ExecutorService:继承executor接口,包含submit和shutdown方法
  • 结果

    • Future:线程返回结果的顶层接口,包含get方法
    • FutureTask是Future的实现类
  • Java 线程的 6 种状态

    • NEW: 初始状态,线程被创建出来但没有被调用 start() 。
    • RUNNABLE: 运行状态,线程被调用了 start()等待运行的状态。
    • BLOCKED:阻塞状态,需要等待锁释放。
    • WAITING:等待状态,表示该线程需要等待其他线程做出一些特定动作(通知或中断)
    • TIME_WAITING:超时等待状态,可以在指定的时间后自行返回而不是像 WAITING 那样一直等待。
    • TERMINATED:终止状态,表示该线程已经运行完毕。
    • 在这里插入图片描述
    • 比对进程的五态模型
      • 在这里插入图片描述
      • 线程的六态模型的区别是
        • 将就绪和运行中合并为运行态,因为通过时间片分配给线程,线程就绪和运行中之间的间隔时间非常短,所以不用单独拆成两个状态
        • 线程多了等待和超时等待

线程池

java线程池思想纠正
线程池不是从里面拿一个线程来进行工作。而是产出一个任务,交给线程池,线程池将任务交付给空闲的线程去执行。

  • ThreadPoolExecutor

    • 核心参数
      • 核心线程数
      • 最大线程数
      • 等待队列最大长度
      • 超时存活时间
      • 线程工厂
    • Executors工具类实现的线程池
      • FixedThreadPool:固定线程数,使用无界等待队列,大量任务堆积等待队列中会出现OOM
      • SingleThreadExecutor:线程池只有一个线程,使用无界等待队列,大量任务堆积等待队列中会出现OOM
      • CachedThreadPool:使用的同步队列,不存储等待任务,只要任务进来,就创建线程执行任务,且允许创建的线程数量为 Integer.MAX_VALUE,会出现OOM
      • ScheduledThreadPool:使用的无界的延迟阻塞队列,内容使用的最小堆排列,同样大量任务堆积等待队列中会出现OOM
    • 线程池的拒绝策略
      • 抛出异常之后拒绝任务
      • 将任务回退给调用者,使用调用者的线程来执行任务
      • 直接丢弃掉
      • 丢弃等待队列中的最早进来的未处理的任务请求
    • 线程池中任务进来的判断流程
      • 在这里插入图片描述
      • 可以看出是先判断等待队列是否可以放入,才判断是否是小于最大线程数,然后创建线程
  • 线程池创建核心参数设置

    • 计算密集型
      • 可以将核心线程数设置为 N(CPU 核心数)+1
      • 最大线程数不适合过大(最大线程数可以稍大于核心线程数),根据实际情况调整。
    • IO密集型
      • 设置核心最大进程数为2N
      • 设置最大线程数为4N
    • 混合型
      • 计算 + 等待
      • 需要结合上面两种进行调优
  • 线程池的参数调整过程

    • 首先根据上面类型设置理论数 (在设置线程数的时候可以稍微往2N方向去考虑)
    • 根据实际情况进行压测
    • 根据压测结果进行调整
    • 循环步骤2和3,直到得到最佳效果
  • 线程池尽量不要放耗时任务

    • 线程池本身的目的是为了提高任务执行效率,避免因频繁创建和销毁线程而带来的性能开销。如果将耗时任务提交到线程池中执行,可能会导致线程池中的线程被长时间占用,无法及时响应其他任务,甚至会导致线程池崩溃或者程序假死。
  • 线程池是如何保证线程不被销毁的呢?

    • 如果队列中没有任务时,核心线程会一直阻塞在获取任务的方法,直到返回任务。而任务执行完后,又会进入下一轮 work.runWork()中循环
  • 线程池中的线程会处于什么状态?

    • RUNNABLE,WAITING,因为要么就在执行任务,要么就在阻塞等待获取
  • 核心线程与非核心线程有区别吗?

    • 没有。被销毁的线程和创建的先后无关。即便是第一个被创建的核心线程,仍然有可能被销毁。大于核心线程数时,线程空闲且超过超时时间会被销毁。

死锁

  • 产生死锁的四个必要条件
    • 互斥条件:该资源任意一个时刻只由一个线程占用。
    • 请求与保持条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放。
    • 不剥夺条件:线程已获得的资源在未使用完之前不能被其他线程强行剥夺,只有自己使用完毕后才释放资源。
    • 循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系。
  • 如何预防死锁? 破坏死锁的产生的必要条件即可
    • 破坏请求与保持条件:一次性申请所有的资源。
    • 破坏不剥夺条件:占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它占有的资源。
    • 破坏循环等待条件:靠按序申请资源来预防。按某一顺序申请资源,释放资源则反序释放。破坏循环等待条件。
  • 常见的预防死锁的方案
    • 银行家算法:是对资源的分配的实现,每次线程请求资源时,判断资源是否足够,如果当前资源分配给线程足够支撑线程完成并释放资源,则分配资源,反之拒绝分配。要求一次性申请所有的资源,并且安装顺序分配资源。破坏请求与保持,破坏循环等待

线程间的同步的方式

  • 互斥:
    • 只有拿到互斥对象的线程才能访问资源
    • synchronized 和 ReentrantLock 都是一次只允许一个线程访问某个资源
  • 信号量:
    • 允许多个线程访问资源,当时线程数必须在信号量允许的范围内
    • Semaphore(信号量)可以用来控制同时访问特定资源的线程数量
  • 事件:通过事件通知的方式实现线程同步。

AQS的关系

  • AQS 是抽象队列同步器(AbstractQueuedSynchronizer),是在java.util.concurrent.locks包下
  • AbstractQueuedSynchronizer这个类是一个抽象类,主要是被子类继承可以很方便实现构造出同步器(ReentrantLock 互斥同步和Semaphore 共享同步)
  • 原理:当一个线程请求资源时,通过CAS操作,判断是否允许线程持有资源,如果CAS操作失败,则将当前线程封装为一个node节点,加入一个双向等待队列的尾部(遵循FIFO)。
  • 通过继承AQS类,需要实现几个方法
    • 在这里插入图片描述
    • boolean tryAcquire(int arg) 独占模式尝试获取锁,AQS中未实现,由子类去实现
    • tryRelease(int arg)尝试释放独占锁,AQS中未实现,由子类去实现,成功释放返回true
    • tryAcquireShared(int arg)尝试获取共享锁,返回负数表示失败,0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源,AQS中未实现,由子类实现
    • tryReleaseShared(int arg)尝试释放锁,释放后允许唤醒后续等待结点返回true,否则返回false,AQS中未实现,需要由子类实现
    • isHeldExclusively() 共享资源是否被独占

通过AQS实现的lock有

  • 可重入锁 ReentrantLock 支持公平、非公平锁
  • 可重入读写锁 ReentrantReadWriteLock 支持公平、非公平锁
  • 信号量 Semaphore 支持公平、非公平锁
  • 线程计数器 CountDownLatch 不支持公平、非公平锁
  • 线程池中worker ThreadPoolExecutor中的worker 不支持公平、非公平锁

CAS

CAS(Compare-and-Swap/Exchange)是一种无锁算法,通过值比较来保证操作的原子性。
在这里插入图片描述

使用AtomicInteger代码讲解CAS的逻辑,核心代码如下

    private volatile int value;
     public final int getAndSet(int newValue) {
        return unsafe.getAndSetInt(this, valueOffset, newValue);
    }

value使用volatile修改保证可见性
this是当前对象的引用
valueOffset是要修改字段在对象地址上的偏移量
newValue是需要新设置的值

    public final int getAndSetInt(Object var1, long var2, int var4) {
        int var5;
        do {
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var4));

        return var5;
    }

首先通过getIntVolatile本地方法获取旧值,循环使用compareAndSwapInt这个方法比对和设置值

CAS的好处

无锁方案相对互斥锁方案,最大的好处就是性能。互斥锁方案为了保证互斥性,需要执行加锁、解锁操作,而加锁、解锁操作本身就消耗性能;同时拿不到锁的线程还会进入阻塞状态,进而触发线程切换,线程切换对性能的消耗也很大。 相比之下,无锁方案则完全没有加锁、解锁的性能消耗,同时还能保证互斥性,既解决了问题,又没有带来新的问题,可谓绝佳方案。

无锁方案相对于互斥锁方案,优点非常多,首先性能好,其次是基本不会出现死锁问题(但可能出现饥饿和活锁问题,因为自旋会反复重试),最后我们所有原子类的方法都是针对一个共享变量的,如果你需要解决多个变量的原子性问题,建议还是使用互斥锁方案。原子类虽好,但使用要慎之又慎。

对于ABA问题可以采用版本号的方式解决,例如AtomicStampedReference 和 AtomicMarkableReference

CAS存在问题

  • 自旋(循环)时间长开销很大,如果CAS失败,会一直进行尝试。
  • 只能保证一个共享变量的原子操作,对多个共享变量操作时
  • ABA问题,在使用CAS前要考虑清楚“ABA”问题是否会影响程序并发

CAS和AQS的关系

  • AQS是一个用来构建线程同步的框架,例如,ReentrantLock和Semaphore等同步器都是基于AQS实现的
  • AQS利用CAS来保证其内部状态(state)的原子性更新

Lock API

所以针对 synchronized 的弊端,JUC 下提供了的新的锁Lock

  • 在使用 synchronized 时,我们要配合使用 wait , notify/notifyAll 来进行线程的等待和通知
  • 在使用 Lock 时我们需要使用 Condition 中提供的await() 、 signal() 、 signalAll()

Semaphore

信号量可以分为以下三种类型:

  • 互斥信号量:任务之间通过互斥信号量访问临界资源,这其实就是锁机制(资源数为1)
  • 计数信号量:任务之间竞争性的访问共享资源(根据实际资源数设置参数)
  • 二值信号量:任务之间的同步机制(开始时资源数为0,一个线程完成之后释放资源,资源数变为1)

ThreadLocal

四大引用

强引用(StrongReference):最传统的“引用”的定义,是指在程序代码之中普遍存在的引用赋值,即类似“Object obj = new Object()”这种引用关系。无论任何情况下,只要强引用关系还存在,垃圾收集器就永远不会回收掉被引用的对象。

软引用(SoftReference):在系统将要发生内存溢出之前,将会把这些对象列入回收范围之中进行第二次回收。如果这次回收后还没有足够的内存,才会抛出内存流出异常。通过 SoftReference 构建软引用。

弱引用(WeakReference):被弱引用关联的对象只能生存到下一次垃圾收集之前。当垃圾收集器工作时,无论内存空间是否足够,都会回收掉被弱引用关联的对象。通过 WeakReference 构建弱引用

虚引用(PhantomReference):一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来获得一个对象的实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。通过PhantomReference 构建虚引用

上面说的对象会被GC收回,前提都是对象不再存在强引用的情况下。

ThreadLocal基本方法

  • 使用ThreadLocal目的:保证线程所修改的属性不被其他线程修改
  • ThreadLocal的方法get的实质是获取当前线程内部的ThreadLocalMap的get方法,key是ThreadLocal,通过hashcode方法计算出ThreadLocal对应的索引下标,然后获取ThreadLocalMap中对应的内容
  • ThreadLocal的方法set的实质是对当前线程内部的ThreadLocalMap进行set,首先判断线程的ThreadLocalMap是否存在,不存在则创建一个并复制到线程内部。set过程中会创建一个ThreadLocal的弱引用作为key进行设置。

ThreadLocal中的软引用引发的问题

  • ThreadLocalMap是Map结构,自然也会发生Hash冲突,HashMap通过拉链发解决的。ThreadLocalMap则是通过开放地址法解决冲突,在计算出的Hash下标的数组中发现已经存在entry,则会向后移动下标,继续找可以存放数据的地方。
  • ThreadLocalMap中每一个key、value都是通过entry存放的,但是由于entry中的key是ThreadLocal的弱引用,所以当ThreadLocal的强引用被赋值null,在下次GC的过程中就会导致ThreadLocal对象被回收,导致entry中key为null,entry也就会被认为是过期数据。
  • 为什么key要使用ThreadLocal的弱引用,而不是直接使用强引用?如果在entry内部ThreadLocal是强引用,在ThreadLocal threadLocal = null;时,相当于ThreadLocal对应的对象已经不能再使用了,但是ThreadLocalMap中取值需要通过ThreadLocal作为key才能get到内容,相当于Map中的数据永远无法获取到,会导致内存泄漏。
  • 而使用ThreadLocal的弱引用,在ThreadLocal强引用被删除,而entry中的key被gc之后就会变为null,通过这个特征就可以在代码中进行回收了。
  • 如何回收,在ThreadLocalMap的set,get方法中都有主动清除存在entry但是key为null得过期数据的逻辑。
  • 如果一直不调用get,set方法,存过期的entry在就会造成内存泄漏。所以在不适用ThreadLocal时,通过remove主动删除过期数据。

几个锁的对应和理解

  • 公平锁和非公平锁:等待锁的过程中是否有插队的
  • 悲观锁和乐观锁:操作之前是否要上锁
  • 共享锁和互斥锁:一个资源是否可以被多个线程持有

ReentrantLock 的概念

  • ReentrantLock是java.util.concurrent.locks包下的,通过AQS实现的悲观锁
  • 原理:ReentrantLock内部有一个抽象类Sync,这个类继承AbstractQueuedSynchronizer(AQS),同时在ReentrantLock内部对Sync有两种实现,公平锁和非公平锁。生成ReentrantLock对象的过程其实就是构建Sync实例对象的过程。同时上锁也是通过Sync实例对象的lock方法实现的。(这块建议看下源码,很好理解)
  • ReentrantLock 的特性是可重入,这块跟是否是公平锁没关系,在获取锁的时候,会判断持有当前资源的线程是不是当前线程,如果是的话,可以直接获取锁
  • 非公平锁,一个线程进来直接会尝试一下CAS,不成功则进入等待队列。成功则会在等待队列前占有资源(直接越过了排队过程,对等待队列中的其他线程是不公平的)
  • 公平锁,在实例化ReentrantLock 对象的时候,通过传入布尔值,来创建公平锁。线程进来,如果有等待的线程,则先进等待队列排队,依次获取资源。

ReadWriteLock

  • 主要是通过分场景优化性能,提升易用性(用于读多写少的场景)
  • 读写锁与互斥锁的一个重要区别就是读写锁允许多个线程同时读共享变量,而互斥锁是不允许的,这是读写锁在读多写少场景下性能优于互斥锁的关键。
  • 基本原则
    • 读锁时,允许多个线程同时读共享变量;但读的时候禁止写
    • 写锁时,只允许一个线程写共享变量;
    • 写锁时,此时禁止读线程读共享变量

StampedLock

  • 他的性能就比读写锁还要好

  • ReadWriteLock 支持两种模式:一种是读锁,一种是写锁。

  • StampedLock 支持三种模式,分别是:写锁、悲观读锁和乐观读。

  • 写锁、悲观读锁的语义和 ReadWriteLock 的写锁、读锁

  • StampedLock 支持乐观读的方式

    • 允许多个线程同时读的情况下还能允许一个线程获取写锁,也就是说不是所有的写操作都被阻塞
    • 读之前,调用乐观读tryOptimisticRead()获取一个stamp,然后读取值,然后再验证一下stamp是否已经被修改(通过validate(stamp)验证)。如果发现被修改,升级为悲观读锁。
  • 不支持重入锁

CountDownLatch 线程计数器

  • 可以等待多个线程就绪之后,启动下一步
  • 可以多个线程等待一个线程再启动下一步

不足

  • CountDownLatch是一次性的,计数器的值只能在构造方法中初始化

CyclicBarrier

  • 是可循环使用(Cyclic)的屏障(Barrier)
  • 让一组线程到达一个屏障(也可以叫同步点)时被阻塞,最后一个线程到达屏障时,屏障才会打开
  • 因为可以reset()。所以CyclicBarrier能处理更为复杂的业务场景时,如果计算发生错误,可以重置计数器,并让线程们重新执行一次

并发体系总结

在这里插入图片描述

LangChain实战:用FAISS搭建本地文档问答系统(含Word文件处理避坑指南) 本文详细介绍了如何利用LangChain框架和FAISS向量数据库构建本地化智能文档问答系统,特别针对Word文档处理中的技术难点提供实用解决方案。通过模块化设计、本地化支持和多格式兼容,实现高效文档处理与精准问答,满足企业对数据隐私和安全的需求。 阅读详情

相关推荐

OBD诊断协议:OBDⅡ (SAE J1979) 和 OBDonUDS (SAE J1979-2) 和ZEV OBD技术架构的详细对比

摘要:文章对比了2025年最新OBD技术标准(SAEJ1979系列)的三大架构:传统OBD-II(已淘汰)、OBDonUDS(燃油/混动车)和ZEVOBD(新能源车)。核心发现:1)OBDonUDS与ZEVOBD共享UDS协议栈和DoIP通信标准,仅应用层数据(DID/DTC)不同;2)物理层统一为CAN+以太网,支持远程诊断和OTA;3)诊断工具需同时兼容J1979-2/3数据库。技术演进呈现"协议统一化、数据专用化"趋势,2027年后所有新车将强制采用新标准。

m0_56482679的博客 2379

带你通俗易懂的理解——线程、多线程与线程池

作者 | wildma 地址 | http://www.jianshu.com/u/645342ca3cad 声明 | 本文是 wildma 原创,已获授权发布,未经原作者允许请勿转载 进程与线程 进程:进程就是正在执行的程序。 线程:是程序执行的一条路径, 一个进程中可以包含多条线程。 通俗理解:例如你打开微信就是打开一个进程,在微信里面和好友视频聊天就是

code小生 8831

地瓜派RDK X5部署YOLOv11n避坑指南:手把手教你解决Softmax算子导致的性能暴跌问题

本文详细介绍了在地瓜派RDK X5开发板上部署YOLOv11n模型时遇到的性能问题及解决方案。通过强制BPU部署Softmax算子,成功将推理速度从7FPS提升至47FPS,并提供了完整的优化流程和技术细节,帮助开发者避免类似性能陷阱。

weixin_42629671的博客 268

多线程(一):通俗易懂的理解线程和进程

通俗易懂的理解线程、进程

m0_55161603的博客 523

AI中台系统设计方案探讨

集成JupyterLab、低代码建模工具(如H2O.ai)、预训练模型库(Hugging Face、PaddleHub)。:通过REST/gRPC接口封装AI能力(如OCR、语音识别),支持流量控制与鉴权(如Kong、Apigee)。:服务注册发现(Consul)、熔断降级(Hystrix)、监控告警(Prometheus+Grafana)。:分布式存储(如HDFS、Ceph)与对象存储(如S3、OSS),支持海量数据高速读写。加密传输(TLS)、动态脱敏(如数据掩码)、访问控制(RBAC)。

reset2021的博客 1031

SAP IDOC实战:如何用EDI实现跨公司采购订单自动生成销售订单(附完整配置步骤)

本文详细解析了如何利用SAP IDOC与EDI技术,实现跨公司采购订单自动生成销售订单的完整流程。通过实战案例,从业务蓝图设计、输出条件配置、伙伴参数设定到IDOC消息类型处理,提供了清晰的配置步骤与故障排查指南,帮助企业打通内部业务流,构建高效的自动化闭环。

weixin_29215815的博客 727

我对Python多线程编程的通俗理解,希望帮助到你!

1 默认启动主线程一般的,程序默认执行只在一个线程,这个线程称为主线程,例子演示如下:导入线程相关的模块 threading:import threading threading的类方法...

算法channel 313

苹果搜索广告ASA开户教程

阅读导航 一、创建账号 1、登录网站 2、填写账号主体信息 3、填写商家和发票信息 4、选择付款方式 二、上传审核材料 1、上传文件 2、请求审批 3、上传文件中的常见问题 一、创建账号 1、用Apple ID登录ASA网站 首先我们进入开户网址:https://app-ads.apple.com/ 如果已拥有Apple ID,直接登录即可,如果没有Apple ID,可以先按照步骤创建Apple ID,再返回登录。 注意,这里登录的Apple ID也有讲究: ① 如果是开发

testflight121的博客 2128

java面试中关于线程有什么知识点

Java多线程与并发编程面试要点精粹: 本文系统梳理了Java多线程核心知识点,涵盖基础概念、线程同步、线程池使用、并发工具及JMM模型等面试高频内容。重点包括:4种线程实现方式(推荐Runnable/Callable/线程池)、线程生命周期五大状态、同步机制(synchronized/volatile/Lock)、线程池参数配置(核心三参数:corePoolSize/maxPoolSize/workQueue),以及JUC工具包中的CountDownLatch/CyclicBarrier等实用组件。特别解

m0_74023628的博客 1083

SAP 系统中的数字签名解决方案及应用案例分析

在当前企业信息化及数字化转型的大背景下,数据安全与身份认证显得尤为重要。数字签名技术作为保障数据真实性和完整性的重要手段,在 SAP 系统中得到了广泛应用。本文将详细探讨 SAP 系统中部分应用场景如何利用数字签名技术满足业务需求,涵盖 SAP Single Sign-On、质量管理、过程工业生产计划以及 SAP ArchiveLink 内容服务器等方面,力求通过深入解读,帮助读者更好地理解和应用这一关键技术。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 526

普通用户也能免费使用 SAP Joule!

点击 SAP Joule 给出的按钮之后,SAP Business Application Studio 左侧显示的界面,就从 SAP Joule 替换成了 SAP Fiori tools 的 Project Accelerator 工具。接下来就是在后者中标准的操作流程了。笔者之前的文章,有朋友提问,既然 ChatGPT,DeepSeek,Grok 这些主流 AI 工具,回答 SAP 相关问题时都经常翻车,那 SAP 自家的 Joule 表现又如何呢?还有朋友评论:如何才能使用 SAP Joule?

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1015

Python多线程通俗易懂快速理解附例子解释

3分钟快速理解python多线程

weixin_41663412的博客 324

华为OD技术面八股_C++_05

汇总华为OD技术面C++方向技术面八股文,提供详细解答。

qq_45776114的博客 413

【Python】Python多任务第1篇:多进程、多线程与协程通俗易懂的理解方式

面试和实际应用中,往往需要与多任务打交道,但是对于多任务,你真的理解到位了吗?本文将分享多进程、多线程与协程通俗易懂的理解方式,希望能对你有帮助。 一、剪刀厂模型(感性认识) 设想这么一个情境,有一个老板想要开个工厂进行生产某件商品(例如剪刀) 他需要花一些财力物力制作一条生产线,这个生产线上有许多的器件以及材料,这些为了能够生产剪刀而准备的资源称之为:进程 只有生产线是不能够进行生产的,所以老...

weixin_43868754的博客 412

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

通俗易通的:Java多线程详解总结

一、基本概念 程序(program): 是为完成特定任务、用某种语言编写的一组指令的集合。即指一 段静态的代码,静态对象。 进程(process):是程序的一次执行过程,或是正在运行的一个程序。是一个动态 的过程:有它自身的产生、存在和消亡的过程。——生命周期 运行中的QQ,运行中的MP3播放器 程序是静态的,进程是动态的 进程作为资源分配的单位,系统在运行时会为每个进程分配不同的内存区域 线程(thread):进程可进一步细化为线程,是一个程序内部的一条执行路径。 若一个进程同一时间并行执行多

486

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

分布式、多进程、多线程的一些通俗理解

此处嵌入式特指基于linux平台,单片机和其他rtos不在讨论范围~ 我从事嵌入式软件开发有6,7个年头,bsp、驱动、应用软件、android hall、framework等都有涉猎。平时除了关注嵌入式行业的发展,也多少对Web、后台服务端、分布式等方向的技术有一些关注。 近期有萌生换个行业方向的想法,想做做后台服务器相关的开发,由于之前工作中并没有这方面的实际需求,只是自己平时关注,了解了些...

qq_37881174的博客 893

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

对多线程的理解

首先,什么是多线程。我的理解是多线程就是多个线程同时进行。比如说买火车票,好几个人同时购买火车票,每一个人购买火车票都是一个线程,多个人同时购买自然就是多线程了。 说到线程,有一个与之相关的概念叫做进程。所谓进程,就是对于程序的一次执行的过程。还是以买火车票为例,买火车票就是进程,因为他要执行买火车票的这个程序。然后呢,一个进程可以有多个线程,但至少得有一个线程,不然就没有意义了。你可以多个人同时买火车票,但起码要有一个人买,不然没人买票跑程序干嘛呢? 对于线程,一般来说有三中创建的方法。第一是继承Thre

NewBeeMu的博客 1163

一文彻底理解synchronized(通俗易懂的synchronized)

一文搞懂synchronized

fu_bobo 9298

NodeJS(一)通俗理解 NodeJS

文章目录前言一、nodeJS是什么?二、nodeJS之前的主流是什么?三、为什么要用nodeJS?总结 前言 nodeJS 一、nodeJS是什么? Node.js 是一个基于 V8 JavaScript 引擎构建的 JavaScript 运行时(runtime)。 官网:http://nodejs.cn/ 也可以理解为用JavaScript写的服务端平台,能运行在服务端的框架。 二、nodeJS之前的主流是什么? NodeJS是近年来比较火的,这一方面得益于其在后端处理高并发的卓越性能,另一方面在no

CathyleeQ的博客 1万+

Java 多线程理解

java多线程,基于Thread类运行。Runnable和Callable都是为了创建任务,其中继承Thread类实现多线程也是实现了 Runnable 接口的一个实例。Future接口以及其衍生任务的执行结果进行取消、查询是否完成、获取结果。Thread和线程池,启动多线程Runnable和Callable创建任务Future接口以及其衍生控制获得任务结果的过程线程的详细状态。

weixin_51147295的博客 221

【Linux/C++多线程篇(二) 】给线程装上“红绿灯”:通俗易懂的同步互斥机制讲解 & C++ 11下的多线程

本文以“交通红绿灯”为喻,通俗易懂地解析多线程编程中的同步互斥机制。文章首先剖析竞态条件成因,随后详解 POSIX 标准下的互斥锁、无名信号量及条件变量 API,并通过生产者 - 消费者模型演示实战用法。此外,深入介绍 C++11 原生线程库,涵盖 std::thread、std::mutex、lock_guard 及 condition_variable 等核心组件。从底层 C 接口到现代 C++ 封装,助你彻底掌握线程安全核心,轻松驾驭多核并发编程。

2501_93095927的博客 1626

多线程Cpp

文章目录0.基本概念1.进程2.线程3.并发3.1 多进程并发3.2 多线程并发4.jion()5.detach()6.jionable()7.注意8.粒度1.线程休眠2.启动线程3.传递参数3.1传递临时对象作为线程参数4.线程id5.传递类对象、智能指针、类成员函数和类对象作为线程参数5.1 传递类对象5.2 传递智能指针5.3 类成员函数5.3 类对象6.数据共享问题:6.1 只读数据6.2 读写数据7.互斥量7.1 互斥量的使用7.2 std::lock_guard()8.死锁8.1概念8.2 死锁

Destiny_的博客 3774

多线程并行和并发区别的简单理解

多线程并行和并发的区别是什么? 目录 多线程并行和并发的区别是什么? 多线程相关概念 进程 线程 此时再来看多线程并行和并发的区别: 并行 并发 多线程相关概念 官方定义是: 多线程是指从软件或者硬件上实现多个线程并发执行的技术。 通俗来讲是: 指一个或多个进程有多条执行路径。 进程 • 指的是可以执行的程序或文件(例如: exe) 可以抽象理解为: 现实生活中的 汽车 线程 • 指的是进程的指定单元,也叫执行路径 可以抽象理解为: ...

Joieeee的博客 4494

关于java中的锁的理解(通俗易懂)

这是我看过的极好的一篇关于锁的机制的介绍,通俗易懂,非常好,采纳,接受,给赞

u012291108的博客 9203

你通俗易懂的理解——线程、多线程与线程池

(2)解决思路:保证一个线程a在操作ticket的过程中,其它线程必须等待,知道线程a操作ticket结束以后,其它线程才可以操作共享数据。需要被同步的代码,在被synchronized包裹以后,就使得一个线程在操作这些代码的过程中,其它线程必须等待。抓的过程,生成异常类对象后将对象抛出,程序不执行其后代码。同步监视器:俗称锁,哪些线程获取了锁,哪个线程就能执行需要被同步的代码。程序是一段代码,进程是程序的执行过程(从创建到使用到消亡),线程。使用线程同步机制(同步代码块或同步方法)

fanTuanye的博客 1214
上一篇: Springboot中的设计模式:根据设计模式的类型
下一篇: Spring MVC 为什么是 MVC 而不是 MVP
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贝多芬也爱敲代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值