温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

JDK线程的基本协作机制wait和notify怎么用

发布时间:2021-10-22 09:52:16 来源:亿速云 阅读:343 作者:柒染 栏目:大数据

这篇文章将为大家详细讲解有关 JDK线程的基本协作机制wait和notify怎么用,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

前言

线程间通信主要是通过wait、notify来实现的,使用这种机制实现线程通信是非常效率的,相比而言,不知道的同学针对线程通信可能只会想到轮询的方式,下次可别再去轮询共享变量了,把线程协作机制用起来。

一、线程协作的要素

首先,如果了解显式锁ReentrantLock或显式条件Condition,我们就会知道锁的队列不止有一个等待队列,还有一个等待条件队列,存放等待被唤醒的线程。 对于用声明式编程synchronized关键字来说,底层也是这种原理,对应的针对等待条件队列入队出队方法就是锁资源的wait/notify/notifyAll方法。但光有这种机制只能表示我们线程可以触发其他线程继续执行,前面说了叫等待条件队列,那条件到底是什么勒?一般来说条件就是线程间共享的一个变量,这个变量用于控制线程等待或继续执行。总结来说,notify一般伴随着一个条件共享变量的改变,wait一般伴随着一个条件共享变量的不满足。比如如下代码:

 synchronized (this) {
                while (!condition) {
                    wait();
                }
            }

最开始condition不满足,该线程放弃CPU执行权,进入等待条件队列,然后等到其他线程做了其他事后,条件共享变量被改变,然后该线程被唤醒,然后继续执行。

二、线程协作的场景

线程间的基本协作机制大致分为以下几种:

  • 生产者/消费者协作模式,生产者线程和消费者线程共享一个队列变量,为了控制队列的长度上限,当队列为满时,限制生产者线程等待,当添加信息到队列时,队列不为空,唤醒消费者队列,当队列为空时限制消费者线程等待,取到信息时,队列不为满,唤醒生产者队列。

  • 同时开始,所有子线程根据一个共享变量等待一个条件,同时开始的意思是主线程改变这个共享变量同时移除所有在等待条件队列中的线程,如模拟仿真程序中,要求多个线程能同时开始。

  • 等待结束,thread.join()方法的底层原理是while(子线程未结束){wait(0)},等待子线程结束。更好的方式实现是通过Java的CountDownLatch类来控制主线程的等待,子线程每结束一个线程计数器减1,主线程的等待条件是计数器为0,使用线程计数器也可以实现同时开始,只需要让子线程共享线程计数器变量,等待条件是线程计数器为0,主线程将一个线程计数器传入多个子线程并运行子线程,在一个时刻将线程计数器countDown为0就行了。这个主要是应用在主从协作模式中,主线程将任务分解为若干个子任务,为每个子任务创建一个线程,主线程在继续执行其他任务之前需要等待每个子任务执行完毕。

  • 异步结果,jdk并发包对异步任务进行了封装,主要用于主从协作场景,如果不想手工创建线程,管理线程可以使用Excutors异步任务执行服务,核心是Future接口的get方法,该方法将等待异步任务返回执行结果,然后才会被唤醒并返回结果。

  • 集合点,并发包中的CyclicBarrier栅栏就是这种场景的应用,一组子线程同时等待所有其他线程到一个地方之后再开始执行下面的逻辑,如一些并行计算场景,每个线程负责一部分计算,然后在集合点等待其他线程完成,所有线程到齐后,交换数据和计算结果,再进行下一次计算。

关于 JDK线程的基本协作机制wait和notify怎么用就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI