Java多线程
文章平均质量分 87
java 给多线程编程提供了内置的支持。 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销。
呆萌宝儿姐
CSDN专家博主、阿里云开发者社区专家博主、51CTO社区专家博主、360书馆认证博主、知乎掘金B站等平台受邀作者。
如遇开发、程序等需求,博客首页下拉加入公众号,私信博主
展开
-
Netty高并发网络编程讲解(附Netty+WebSocket实战)
Netty 是一个广泛使用的 Java 网络编程框架,它提供了一个易于使用的 API 客户端和服务器,它活跃和成长于用户社区,像大型公司 Facebook 以及流行 开源项目如 Infinispan, HornetQ, Vert.x, Apache Cassandra 和 Elasticsearch 等,都利用其强大的对于网络抽象的核心代码。原创 2023-10-10 10:17:16 · 531 阅读 · 0 评论 -
一文就懂AQS!
AbstractQueuedSynchronized(AQS),是抽象的队列式的同步器,AQS定义了一套多线程访问共享资源的同步器框架**,许多同步类实现都依赖于它,例如常用的ReentrantLock/Semaphore/CountDownLatch等AQS是一个用来构建锁和其他同步组件的基础框架,使用AQS可以简单且高效地构造出应用广泛的同步器,它提供了一个FIFO队列(先进先出队列),可以看成是一个用来实现同步锁以及其他涉及到同步功能的核心组件。原创 2023-02-23 14:01:13 · 1738 阅读 · 0 评论 -
死锁产生的条件及其预防
破坏“不可剥夺”条件:一个进程不能获得所需要的全部资源时便处于等待状态,等待期间他占有的资源将被隐式的释放重新加入到 系统的资源列表中,可以被其他的进程使用,而等待的进程只有重新获得自己原有的资源以及新申请的资源才可以重新启动,执行。破坏“循环等待”条件:采用资源有序分配其基本思想是将系统中的所有资源顺序编号,将紧缺的,稀少的采用较大的编号,在申请资源时必须按照编号的顺序进行,一个进程只有获得较小编号的进程才能申请较大编号的进程。,Pn},其中P1等待P2所占有的某一资源,P2等待P3所占有的某一源,…原创 2022-09-04 15:21:23 · 1858 阅读 · 0 评论 -
图解进程的(三种、五种)状态
运行:当一个进程在处理机上运行时,则称该进程处于运行状态。处于此状态的进程的数目小于等于处理器的数目,对于单处理机系统,处于运行状态的进程只有一个。在没有其他进程可以执行时(如所有进程都在阻塞状态),通常会自动执行系统的空闲进程。阻塞:也称为等待或睡眠状态,一个进程正在等待某一事件发生(例如请求I/O而等待I/O完成等)而暂时停止运行,这时即使把处理机分配给进程也无法运行,故称该进程处于阻塞状态。就绪:当一个进程获得了除处理机以外的一切所需资源,一旦得到处理机即可运行,则称此进程处于就绪状态。原创 2022-09-03 21:56:11 · 5274 阅读 · 2 评论 -
ReentrantLock原理详解
ReentrantLock是可重入的独占锁,同时只能有一个线程可以获取该锁,其他获取该锁的线程会被阻塞而被放入该锁的AQS阻塞队列里面。AbstractQueuedSynchronizer简称AQSAQS是一个用于构建锁和同步容器的框架。事实上concurrent包内许多类都是基于AQS构建,例如ReentrantLock,Semaphore,CountDownLatch,ReentrantReadWriteLock,FutureTask等。AQS解决了在实现同步容器时设计的大量细节问题。原创 2022-10-13 21:31:07 · 1509 阅读 · 0 评论 -
说一说Java线程有多少种状态,如何转换
在线程的生命周期中,它要经过新建(New)、就绪(Ready)、运行(Running)、阻塞(Blocked)和死亡(Dead)5种状态。尤其是当线程启动以后,它不可能一直“霸占”着CPU独自运行,所以CPU需要在多条线程之间切换,于是线程状态也会多次在运行、就绪之间切换。原创 2022-10-27 21:08:16 · 1100 阅读 · 0 评论 -
Java线程调度及相关函数
join()方法通常由使用线程的程序调用,以将大问题划分成许多小问题,每个小问题分配一个线程。让当前线程让位,让给其它线程使用。yield()方法的执行会让当前线程从“运行状态”回到“就绪状态”。当在某个程序执行流中调用其他线程的join()方法时,调用线程将被阻塞,直到被join()方法加入的join线程执行完为止。注意:在回到就绪之后,有可能还会再次抢到,然后过了很短时间就又运行了,所以可能会出现看起来像没调用yield()一样。那个线程的优先级比较高,抢到的CPU时间片的概率就高一些/多一些。原创 2022-11-01 16:54:46 · 1198 阅读 · 0 评论 -
Java中锁升级的探究
JDK 1.6之前,synchronized 还是一个重量级锁,是一个效率比较低下的锁。但是在JDK 1.6后,JVM为了提高锁的获取与释放效率对synchronized 进行了优化,引入了偏向锁和轻量级锁 ,从此以后锁的状态就有了四种:无锁、偏向锁、轻量级锁、重量级锁。并且四种状态会随着竞争的情况逐渐升级,而且是不可逆的过程,即不可降级,这四种锁的级别由低到高依次是:无锁、偏向锁,轻量级锁,重量级锁。原创 2022-10-29 19:16:19 · 1244 阅读 · 0 评论 -
Java多线程:LongAdder 原子操作增强类
LongAdder是jdk8新增的用于并发环境的计数器,目的是为了在高并发情况下,代替AtomicLong/AtomicInt,成为一个用于高并发情况下的高效的通用计数器。说LongAdder比在高并发时比AtomicLong更高效阿里开发手册推荐jdk8使用LongAdder替代AtomicLong现在,在处理高并发计数时,应该优先使用LongAdder,而不是继续使用AtomicLong。当然,线程竞争很低的情况下进行计数,使用Atomic还是更简单更直接,并且效率稍微高一些。原创 2022-11-08 16:18:07 · 1469 阅读 · 0 评论 -
Java多线程:CopyOnWriteArrayList 实现原理
通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。正如其名字一样,在写操作时会复制一份新的List,在新的List上完成写操作,然后再将原引用指向新的List。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,当然,这里读到的数据可能不是最新的。而写操作的时候,则首先将容器复制一份,然后在新的副本上执行写操作,这个时候。结束之后再将原容器的引用指向新容器。原创 2022-11-07 21:07:07 · 1681 阅读 · 0 评论 -
Java多线程:BlockingQueue实现原理(Condition原理)
当调用 Condition对象的 await方法后,当前线程会释放锁并等待,而其他线程调用 Condition 对象的 signal 或者 signalall 方法通知并被阻塞的线程,然后自己执行unlock释放锁,被唤醒的线程获得之前的锁继续执行,最后释放锁。要注意的是,如果等地队列中的节点被唤醒,唤醒节点的线程开始尝试获取同步状态。当调用 Condition 的 await() 方法(或者以 await开头的方法),会使得当前线程进入等待队列,并且释放锁,同时线程的状态变为等待状态。原创 2022-11-07 23:34:43 · 1441 阅读 · 0 评论 -
Java多线程:线程间通信方式
这三个方法都是Condition接口中的方法,该接口是在Java 1.5中出现的,它用来替代传统的wait+notify实现线程间的协作,它的使用依赖于 Lock。反之,当一个线程被wait后,就会进入阻塞队列,等待被唤醒。案例步骤:通信是在不同线程间的通信,一个线程处于wait状态阻塞等待被唤醒,另一个线程通过notify或者notifyAll唤醒,当前的唤醒操作必须是作用与同一个对象,注意在进行唤醒和阻塞时必须要加锁的,加锁需要使用synchronized关键字。程序没有结束,他会一直读取阻塞队列。原创 2022-11-08 10:04:10 · 2041 阅读 · 0 评论 -
Java并发工具类:Semaphore
我们还能发现,在非公平模式工人的总工作量高于公平模式的工人总工作量时,非公平模式下总会有某些工人工(特别是工人0、1、2)作量更多,而另一些工人工作量更少,这就是线程饥饿(就是现在卷起来的环境)!公平模式会确保所有等待的获取信号量的线程按照先进先出的顺序获取信号量,而非公平模式则没有这个保证。如果为0,则拒绝访问。实际上公平与非公平只是在获取信号量的时候得到体现,它们的释放信号量的方法都是一样的,这就类似于ReentrantLock:公平与非公平只是在获取锁的时候得到体现,它们的释放锁的方法都是一样的。原创 2022-10-31 15:11:30 · 1250 阅读 · 0 评论 -
Java多线程:线程池详解(2)
因为先执行完的任务就要等后执行完的任务,最终的时间仍然取决于后执行完的任务,而且还要加上任务拆分与合并的开销,得不偿失。:如果所有的任务都已终止了,workerCount (有效线程数) 为0,线程池进入该状态后会调用 terminated() 方法进入TERMINATED 状态。:关闭状态,不再接受新提交的任务,但却可以继续处理阻塞队列中已保存的任务。:不能接受新任务,也不处理队列中的任务,会中断正在处理任务的线程。:能接受新提交的任务,并且也能处理阻塞队列中的任务。原创 2022-08-21 22:03:54 · 1381 阅读 · 0 评论 -
ThreadLocal 应用及其原理详解
ThreadLocal中get方法的实现逻辑,获取当前线程,取出当前线程的ThreadLocalMap,用当前的threadlocal作为key在ThreadLocalMap查找,如果存在不为空的Entry,就返回Entry中的value,否则就会执行初始化并返回默认的值。如图,在Hash表索引1的位置存了key=name,再向它添加key=hobby的时候,假设计算得到的索引也是1,那么这个时候发生哈希冲突,而开放开放定址法就是按照顺序向后找到一个空闲的位置,来存储这个冲突的key。原创 2022-08-21 21:28:36 · 1577 阅读 · 0 评论 -
volatile关键字是干什么的?他是怎样实现的?
JMM 试图屏蔽各种硬件和操作系统的内存访问差异,以实现让 Java 程序在各种平台下都能达到一致的内存访问效果。原创 2022-08-21 15:08:45 · 1274 阅读 · 0 评论 -
Java多线程:生产者消费者模型
一类是生产者线程用于生产数据一类是消费者线程用于消费数据为了解耦生产者和消费者的关系,通常会采用共享的数据区域,就像是一个仓库生产者生产数据之后直接放置在共享数据区中,并不需要关心消费者的行为消费者只需要从共享数据区中去获取数据,并不需要关心生产者的行为我们来看一个经典案例,可经典了,上课学,代码学,很多地方都会学到。...原创 2022-07-16 10:28:57 · 1990 阅读 · 0 评论 -
Java多线程:线程状态探究
当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。线程对象在不同的时期有不同的状态。那么Java中的线程存在哪几种状态呢?Java中的线程状态被定义在了java.lang.Thread.State枚举类中,State枚举类的源码如下:翻译过来就是我们可以看到Java中的线程存在6种状态,每种线程状态的含义如下各个状态的转换,如下图所示:需求:编写一段代码,依次显示一个线程的这些状态:NEW -> RUNNABLE -> TIME_WAITING -> RUNNABLE ->原创 2022-07-16 11:21:14 · 1288 阅读 · 0 评论 -
Java 多线程实现的三种方式
运行结果如下:为什么要重写run()方法?run()方法和start()方法的区别?运行结果如下:运行结果如下:实现Runnable、Callable接口继承Thread类原创 2022-07-14 08:40:19 · 1479 阅读 · 0 评论 -
Java多线程:阻塞队列与等待唤醒机制初探
阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。...原创 2022-07-16 10:52:32 · 2063 阅读 · 0 评论 -
Java多线程:线程操作的原子性问题
概述 : 原子性是指在一次操作或者多次操作中,要么所有的操作全部都得到了执行并且不会受到任何因素的干扰而中断,要么所有的操作都不执行,多个操作是一个不可以分割的整体。例如一个送冰淇淋的案例:开启100条线程,每个线程送100个冰淇淋。代码实现 :运行结果如下:从结果看出,最后不是10000个冰淇淋,有些count++操作被“打断”了。代码总结 : count++ 不是一个原子性操作, 他在执行的过程中,有可能被其他线程打断,并且说明 volatile关键字不能保证原子性解决方案 : 我们可以给coun原创 2022-07-16 14:52:50 · 1694 阅读 · 0 评论 -
Java多线程:线程池详解(1)
线程池在启动的时,会创建大量空闲线程,当我们向线程池提交任务的时,线程池就。系统创建一个线程的成本是比较高的,因为它涉及到与操作系统交互,当程序中需要创建大量生存期很短暂的线程时,频繁的创建和销毁线程对系统的资源消耗有可能大于业务处理是对系。等待下一次任务的执行。通过控制台的输出,我们可以看到次策略没有通过线程池中的线程执行任务,而是直接调用任务的run()方法绕过线程池直接执行。概述JDK对线程池也进行了相关的实现,在真实企业开发中我们也很少去自定义线程池,而是使用JDK中自带的线程池。...原创 2022-07-16 13:22:56 · 1713 阅读 · 0 评论 -
Java多线程:线程同步详解
线程死锁是指由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行。原创 2022-07-16 09:53:10 · 3139 阅读 · 1 评论 -
Java多线程:设置和获取线程名称
我们可以通过调用设置线程名称的API进行设置方法名说明将此线程的名称更改为等于参数name返回此线程的名称返回对当前正在执行的线程对象的引用i原创 2022-07-16 08:06:42 · 1804 阅读 · 0 评论 -
Java 守护线程初探
Java提供了两种线程:守护线程和用户线程守护线程,是指在程序运行时在后台提供一种通用服务的线程,这种线程并不属于程序中不可或缺的部分。通俗点讲,任何一个守护线程都是整个JVM中所有非守护线程的"保姆"。用户线程和守护线程几乎一样,唯一的不同之处在于如果用户线程已经全部退出运行,只剩下守护线程存在了,JVM也就退出了。因为当所有非守护线程结束时,没有了被守护者,守护线程也就没有工作可做,当然也就没有继续执行的必要了,程序就会终止,同时会杀死所有的"守护线程",也就是说只要有任何非守护线程还在运行,程序就不会转载 2022-07-07 11:39:14 · 164 阅读 · 0 评论 -
Java多线程:线程休眠与线程优先级
随机性假如计算机只有一个CPU,那么CPU在某一个时刻只能执行一条指令,线程只有得到CPU时间片,也就是使用权,才可以执行指令。所以说多线程程序的执行是有随机性,因为谁抢到CPU的使用权是不一定的。注意优先级高的线程获取的CPU时间片相对多一些,而不是一直都是优先级高的运行,只是说他抢到CPU的几率更高。如不设置优先级时候调用getPriority()方法,他会直接打印5。查看源码,我们可以看到优先级数值,默认是5,最大10,最小1。当优先级相同时候抢占式调度选择线程时是随机性的。...原创 2022-07-16 08:31:56 · 1290 阅读 · 0 评论 -
synchronized 实现原理
两种同步方式本质上没有区别,只是方法的同步是一种隐式的方式来实现,无需通过字节码来完成。两个指令的执行是JVM通过调用操作系统的互斥原语mutex来实现,被阻塞的线程会被挂起、等待重新调度,会导致“用户态和内核态”两个态之间来回切换,对性能有较大影响。synchronized关键字经过Javac编译之后,会在同步块的前后分别形成monitorenter和monitorexit这两个字节码指令。这两个字节码指令都需要一个reference类型的参数来指明要锁定和解锁的对象。......原创 2022-08-17 11:21:50 · 3939 阅读 · 3 评论 -
10张图教你同步与异步(转载)
在这篇文章中我们从各种场景分析了同步与异步这两个概念,但是不管在什么场景下,同步往往意味着双方要相互等待、相互依赖,而异步意味着双方相互独立、各行其是。希望本篇能对大家理解这两个重要的概念有所帮助。...转载 2022-07-16 08:50:05 · 1731 阅读 · 0 评论 -
Java并发工具类:CountDownLatch
之前的一些并发工具类仍然不能满足一些特定的需求,比如让某一条线程要进行整理最后数据,那么他得先等待其余线程操作数据的线程完成后在执行,如果不给上面两个工具类加锁操作是很难完成对这样复杂的数据操作编写业务的。如果当前线程的孩子吃完了手里的所有糖果了,那么就调用countDown()方法,将计数器-1,那么我们重写的run方法里就可以这么写。最后母亲线程就需要在运行时进行await等待,等到计数器为0时才会唤醒等待,进行收拾桌子的操作。有这么一个案例妈妈等三个孩子吃完糖果然后收拾桌子。...原创 2022-07-17 17:42:14 · 1350 阅读 · 0 评论 -
Java多线程:volatile关键字
当A线程修改了共享数据时,B线程没有及时获取到最新的值,如果还在使用原先的值,就会出现问题堆内存是唯一的,每一个线程都有自己的线程栈。每一个线程在使用堆里面变量的时候,都会先拷贝一份到变量的副本中。在线程中,每一次使用是从变量的副本中获取的。......原创 2022-07-17 08:44:56 · 1304 阅读 · 0 评论 -
盘点 Java 中的那些个锁
锁有四种状态:无锁状态、偏向锁、轻量级锁、重量级锁随着锁的竞争,锁的状态会从偏向锁到轻量级锁,再到重量级锁。而且锁的状态只有升级,没有降级。也就是只有偏向锁->轻量级锁->重量级锁,没有重量级锁->轻量级锁->偏向锁。锁名称描述应用场景偏向锁线程在大多数情况下并不存在竞争条件,使用同步会消耗性能,而偏向锁是对锁的优化,可以消除同步,提升性能。当一个线程获得锁,会将对象头的锁标志位设为01,进入偏向模式.偏向锁可以在让一个线程一直持有锁,在其他线程需要竞争锁的时候,再释放锁。只有一个线程进入临界区。.....原创 2022-08-17 10:22:24 · 1449 阅读 · 0 评论 -
Java多线程:volatile关键字案例
当A线程修改了共享数据时,B线程没有及时获取到最新的值,如果还在使用原先的值,就会出现问题堆内存是唯一的,每一个线程都有自己的线程栈。每一个线程在使用堆里面变量的时候,都会先拷贝一份到变量的副本中。在线程中,每一次使用是从变量的副本中获取的。...原创 2022-07-16 14:23:48 · 1405 阅读 · 0 评论