并发编程——线程中sleep(),yield(),join(),wait(),notify(),notifyAll()区别
前言
今天简单的讲一讲线程中sleep(),join(),yield(),wait(),notify(),notifyAll()这些方法的使用以及区别。
不过在讲这些方法之前,需要简单的介绍一下锁池和等待池的概念。
专栏推荐:
并发编程专栏
锁池和等待池
1.锁池
所有需要竞争同步锁的线程都会放在锁池当中,比如当前对象的锁已经被其中一个线程得到,则其他线程需要在这个锁池进行等待,当前面的线程释放同步锁后锁池中的线程去竞争同步锁,当某个线程得到后会进入就绪队列进行等待cpu资源分配。
2.等待池
当我们调用wait()方法后,线程会放到等待池当中,等待池的线程是不会去竞争同步锁。只有调用了notify()或notifyAll()后等待池的线程才会开始去竞争锁,notify()是随机从等待池选出一个线程放到锁池,而notifyAll()是将等待池的所有线程放到锁池当中
sleep()
首先看一下sleep方法的源码,我们发现sleep是一个静态方法,它接受一个long类型的毫秒值参数,而且是一个本地方法(native修饰),而且会抛出InterruptedException(中断异常)。
sleep()这个方法的使用很简单,因为它是一个Thread的静态方法,所以就可以直接Thread.sleep(毫秒值),休眠指定的毫秒数。
1、使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会执行。但是时间到了之后线程会进入就绪队列,重新去竞争cpu资源。
2.sleep()会释放cpu资源,但是不会释放同步锁(类锁和对象锁)
例如有两个线程同时执行(没有synchronized)一个线程优先级为MAX_PRIORITY,另一个为MIN_PRIORITY,如果没有Sleep()方法,只有高优先级的线程执行完毕后,低优先级的线程才能够执行;但是高优先级的线程sleep(500)后,低优先级就有机会执行了。
总之,sleep()可以使低优先级的线程得到执行的机会,当然也可以让同优先级、高优先级的线程有执行的机会。
yield()
使当前正在执行的线程向另一个线程交出运行权。注意这是一个静态方法。
该方法与sleep()类似,只是不能由用户指定暂停多长时间,并且yield()方法只能让同优先级的线程有执行的机会。
1、yield()执行后线程直接进入就绪状态。
2、yield()会释放cpu资源,但是不会释放同步锁(类锁和对象锁)
join()
执行后线程进入阻塞状态,例如在线程B中调用线程A的join(),那线程B会进入到阻塞队列,直到join结束或中断线程B才开始进入阻塞队列。
可以实现一个线程的顺序执行。
*下面举一个小例子:
我排队打饭,smile女神来了,我让她先打饭,但是这个时候她男朋友来了,smile女神让他男朋友先打饭。呜呜呜~~~~*
public class UseJoin {
static class Smile implements Runnable {
private Thread thread;
public Smile(Thread thread) {
this.thread = thread;
}
public Smile() {
}
public void run() {
System.out.println("smile开始排队打饭.....");
try {
if(thread!=null) thread.join();
} catch (InterruptedException e) {
}
SleepTools.second(2);//休眠2秒
System.out.println(Thread.currentThread().getName()
+ " smile打饭完成.");
}
}
static class SmileBoyfriend implements Runnable {
public void run() {
SleepTools.second(2);//休眠2秒
System.out.println("smileBoyfriend开始排队打饭.....");
System.out.println(Thread.currentThread().getName()
+ " smileBoyfriend打饭完成.");
}
}
public static void main(String[] args) throws Exception {
SmileBoyfriend smileBoyfriend = new SmileBoyfriend();
Thread sbf = new Thread(smileBoyfriend);
Smile smile = new Smile(sbf);
Thread s = new Thread(smile);
s.start();//我排队打饭
sbf.start();//smile女神来了,但是这个时候她男朋友来了,smile女神让他男朋友先打饭
System.out.println("chaoCode开始排队打饭.....");
s.join();
Thread.sleep(2000);//让主线程休眠2秒
System.out.println(Thread.currentThread().getName() + " chaoCode打饭完成.");
}
}
执行结果,可想而知,抱抱可怜的自己。
wait()和notify()、notifyAll()
1、wait方法用于协调多个线程对共享数据的存取,所以必须在Synchronized语句块内使用
2、wait()方法使当前线程暂停执行并释放会cpu资源,以及同步锁(类锁和对象锁)
3、调用wait()后必须调用notify()或notifyAll()后线程才会从等待池进入到锁池,当我们的线程竞争得到同步锁后就会重新进入绪状态等待cpu资源分配
当调用notify()方法后,将从对象的等待池中移走一个任意的线程并放到锁标志等待池中,只有锁标志等待池中线程能够获取锁标志;如果锁标志等待池中没有线程,则notify()不起作用。
notifyAll()则从对象等待池中移走所有等待那个对象的线程并放到锁标志等待池中。
注意:
1、这三个方法都是java.lang.Object的方法。
2、notif()方法要配合wait()方法使用,一般在wait()之后调用或者在线程结束时调用才会成功。
感谢诸君的观看,文中如有纰漏,欢迎在评论区来交流。如果这篇文章帮助到了你,欢迎点赞关注。
并发编程——线程中sleep(),yield(),join(),wait(),notify(),notifyAll()区别的更多相关文章
- 转:【Java并发编程】之十:使用wait/notify/notifyAll实现线程间通信的几点重要说明
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17225469 在Java中,可以通过配合调用Object对象的wait()方法和no ...
- 【Java并发编程】之十:使用wait/notify/notifyAll实现线程间通信的几点重要说明
在Java中,可以通过配合调用Object对象的wait()方法和notify()方法或notifyAll()方法来实现线程间的通信.在线程中调用wait()方法,将阻塞等待其他线程的通知(其他线程调 ...
- 并发编程学习笔记(12)----Fork/Join框架
1. Fork/Join 的概念 Fork指的是将系统进程分成多个执行分支(线程),Join即是等待,当fork()方法创建了多个线程之后,需要等待这些分支执行完毕之后,才能得到最终的结果,因此joi ...
- java并发编程 线程基础
java并发编程 线程基础 1. java中的多线程 java是天生多线程的,可以通过启动一个main方法,查看main方法启动的同时有多少线程同时启动 public class OnlyMain { ...
- java线程中的sleep/wait/notify/yield/interrupt方法 整理
java线程中的sleep/wait/notify/yield/interrupt方法 sleep 该方法能够使当前线程休眠一段时间 休眠期间,不释放锁 休眠时间结束之后,进入可执行状态,加入到线程就 ...
- Java 并发编程 | 线程池详解
原文: https://chenmingyu.top/concurrent-threadpool/ 线程池 线程池用来处理异步任务或者并发执行的任务 优点: 重复利用已创建的线程,减少创建和销毁线程造 ...
- Python并发编程-线程同步(线程安全)
Python并发编程-线程同步(线程安全) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 线程同步,线程间协调,通过某种技术,让一个线程访问某些数据时,其它线程不能访问这些数据,直 ...
- 读Java并发编程实践中,向已有线程安全类添加功能--客户端加锁实现示例
在Java并发编程实践中4.4中提到向客户端加锁的方法.此为验证示例,写的不好,但可以看出结果来. package com.blackbread.test; import java.util.Arra ...
- java多线程之yield,join,wait,sleep的区别
Java多线程之yield,join,wait,sleep的区别 Java多线程中,经常会遇到yield,join,wait和sleep方法.容易混淆他们的功能及作用.自己仔细研究了下,他们主要的区别 ...
随机推荐
- [Django REST framework - 视图组件之视图基类、视图扩展类、视图子类、视图集]
[Django REST framework - 视图组件之视图基类.视图扩展类.视图子类.视图集] 视图继承关系 详图见文章末尾 视图组件可点我查看 两个视图基类:APIView.GenericAP ...
- 955.WLB 不加班公司名单!再新增 5 家公司!
大家好!我是<Visual Studio Code 权威指南>的作者韩骏.相信不少童鞋都是因为 VS Code 认识到我:也许是用了我写的 20 多个 VS Code 插件(比如 Code ...
- python之list列表(基础篇)
特点:1.有序的 2.可以存放多个元素 3.每个元素可以是任何数据类型,4,通过下标值访问1,定义一个空列表 2,定义一个非空列表 3.访问列表中的元素(同str类型) 4,切片与步长(同str类型 ...
- 第9章:Ingress
9.1 Ingress为弥补NodePort不足而生 1 单独用service暴露服务的方式,在实际生产环境中不太合适 ClusterIP 只能在集群内部访问. NodePort 方式的话,测试环境使 ...
- .NET Core 对象池的使用
昨天在『.NET 大牛之路』技术群和大家聊到了对象池的话题,今天展开详细讲讲这个知识点. 池这个概念大家都很熟悉,比如我们经常听到数据库连接池和线程池.它是一种基于使用预先分配资源集合的性能优化思想. ...
- buu 刮开有奖
一.查壳, 二.拖入ida,分析 直接搜字符串完全没头绪,在看了大佬的wp才找到了,关键函数. 明显那个String就是我们要求的flag,要开始分析程序. 字符串长度为8,同时这个函数对字符串进行了 ...
- B 站崩了,总结下「高可用」和「异地多活」
你好,我是悟空. 一.背景 不用想象一种异常场景了,这就真实发生了:B 站晚上 11 点突然挂了,网站主页直接报 404. 手机 APP 端数据加载不出来. 23:30 分,B 站做了降级页面,将 4 ...
- 懂得分享 Linux 配置NFS共享服务
部署YUM仓库及NFS共享服务一.YUM概述 YUM (Yellow dog Updater Modified)二.准备安装源 ① 软件仓库的提供方式 ② RPM软件包的来源 ...
- C语言:输出各位整数的数字
#include <stdio.h> main() { int i,a,b,c,d,e; printf("请输入四位整数:\n"); scanf("%d&qu ...
- c语言:大纲
C语言大纲:1.C语言程序设计知识(1)基本数据类型与简单程序设计(2)分支程序设计(3)循环程序设计(4)数组(5)函数(6)结构体(7)指针2.C语言程序设计(1)顺序结构的程序设计(2)分支结构 ...