前言

今天简单的讲一讲线程中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()区别的更多相关文章

  1. 转:【Java并发编程】之十:使用wait/notify/notifyAll实现线程间通信的几点重要说明

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17225469    在Java中,可以通过配合调用Object对象的wait()方法和no ...

  2. 【Java并发编程】之十:使用wait/notify/notifyAll实现线程间通信的几点重要说明

    在Java中,可以通过配合调用Object对象的wait()方法和notify()方法或notifyAll()方法来实现线程间的通信.在线程中调用wait()方法,将阻塞等待其他线程的通知(其他线程调 ...

  3. 并发编程学习笔记(12)----Fork/Join框架

    1. Fork/Join 的概念 Fork指的是将系统进程分成多个执行分支(线程),Join即是等待,当fork()方法创建了多个线程之后,需要等待这些分支执行完毕之后,才能得到最终的结果,因此joi ...

  4. java并发编程 线程基础

    java并发编程 线程基础 1. java中的多线程 java是天生多线程的,可以通过启动一个main方法,查看main方法启动的同时有多少线程同时启动 public class OnlyMain { ...

  5. java线程中的sleep/wait/notify/yield/interrupt方法 整理

    java线程中的sleep/wait/notify/yield/interrupt方法 sleep 该方法能够使当前线程休眠一段时间 休眠期间,不释放锁 休眠时间结束之后,进入可执行状态,加入到线程就 ...

  6. Java 并发编程 | 线程池详解

    原文: https://chenmingyu.top/concurrent-threadpool/ 线程池 线程池用来处理异步任务或者并发执行的任务 优点: 重复利用已创建的线程,减少创建和销毁线程造 ...

  7. Python并发编程-线程同步(线程安全)

    Python并发编程-线程同步(线程安全) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 线程同步,线程间协调,通过某种技术,让一个线程访问某些数据时,其它线程不能访问这些数据,直 ...

  8. 读Java并发编程实践中,向已有线程安全类添加功能--客户端加锁实现示例

    在Java并发编程实践中4.4中提到向客户端加锁的方法.此为验证示例,写的不好,但可以看出结果来. package com.blackbread.test; import java.util.Arra ...

  9. java多线程之yield,join,wait,sleep的区别

    Java多线程之yield,join,wait,sleep的区别 Java多线程中,经常会遇到yield,join,wait和sleep方法.容易混淆他们的功能及作用.自己仔细研究了下,他们主要的区别 ...

随机推荐

  1. 即时通信之 SignalR

    即时通信在日常的web开发场景中经常使用,本篇主要回顾一下SignalR的实现原理和通过例子说明如何在.NET Core 中使用. SingnalR 应用 需要从服务器进行高频更新的应用程序.例如游戏 ...

  2. 14、redis安装及数据类型

    14.0.服务器配置: 服务器名称 ip地址 controller-node1 172.16.1.90 14.1.什么是redis: 1.redis的特点: (1)redis是一个开源的使用c语言编写 ...

  3. 2020牛客NOIP赛前集训营-普及组(第二场) 题解

    目录 T1 面试 描述 题目描述 输入描述: 输出描述: 题解 代码 T2 纸牌游戏 描述 题目描述 输入描述: 输出描述: 题解 代码 T3 涨薪 描述 题目描述 输入描述: 输出描述: 题解 代码 ...

  4. CentOS-关闭防火墙和禁用安全策略

    关闭防火墙 默认使用的是firewall作为防火墙 查看防火墙状态 $ firewall-cmd --state 停止firewall $ systemctl stop firewalld.servi ...

  5. Raspberry Pi:树莓派开发板配置USB启动系统

    准备材料 树莓派4B U盘 TF卡 树莓派基础镜像2020-08-20稳定版(这个系统是必须的并拷录在TF卡) Kali树莓派系统(这个是我想要学习的系统,大家可以准备自己的系统,拷录在U盘的) SD ...

  6. HTTP:HTTP请求头和响应头详解

    HTTP请求报文 HTTP 请求报文由3部分组成(请求行+请求头+请求体) HTTP请求报文分析  1. 是请求方法,GET和POST是最常见的HTTP方法,初次以外还包括 DELETE.HEAD.O ...

  7. 1.3.5、通过Method匹配

    server: port: 8080 spring: application: name: gateway cloud: gateway: routes: - id: guo-system4 uri: ...

  8. SpringMVC(10)实现注解式权限验证

    在项目中如何处理出现的异常,在每个可能出现异常的地方都写代码捕捉异常?这显然是不合理的,当项目越来越大是也是不可维护的.那么如何保证我们处理异常的代码精简且便于维护呢?这就是本篇要讲的内容->异 ...

  9. 「CF1208G」 Polygons

    「CF1208G」 Polygons 似乎我校神犇在很久以前和我提过这题? 首先有一点显而易见:这 \(k\) 个多边形肯定至少有一个公共的顶点.假设我们将此点定义为起点. 那么对于一个正 \(n\) ...

  10. 学生信息管理系统--基于jsp技术和MySQL的简单增删改查

    web实现增删改查的方式有很多啊,对于初学者来说当然是要先了解各部分的传值的方式.本篇博客从jsp技术的最基础方面进行说明. 一.什么是jsp技术 首先,我们要了解什么是jsp技术. jsp技术是基于 ...