前言

今天简单的讲一讲线程中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. 7、Oracle通过客户端(sqlplus)登录认证用户的方式

    select version from v$instance; #查看当前数据库的版本 192.168.31.5:1521/orcl 7.1.操作系统认证: 1.Oracle认为操作系统用户是可靠的, ...

  2. 案例分享:Qt西门子机床人机界面以及数据看板定制(西门子通讯,mysql数据库,生产信息,参数信息,信息化看板,权限控制,播放器,二维图表,参数调试界面)

    若该文为原创文章,转载请注明原文出处本文章博客地址:https://blog.csdn.net/qq21497936/article/details/118685521 长期持续带来更多项目与技术分享 ...

  3. 获取 Windows 密码「GitHub 热点速览 v.21.28」

    作者:HelloGitHub-小鱼干 安全问题一直是 GitHub 的一大热点,因为数据安全问题诞生的各类自托管服务便是.而本周周榜上的 2 个和安全主题相关的项目,有些不同.mimikatz 是个老 ...

  4. 锁&事务

    一.概述: 锁:是计算机协调多个进程或线程并发访问某一资源的机制,数据库中最重要的资源.数据库既要保证并发性,又要保证数据的一致性,所以锁机制也更复杂.在计算机科学中,锁(lock)或互斥(mutex ...

  5. XCTF(MISC) 图片隐写

    题目描述:菜猫给了菜狗一张图,说图下面什么都没有 1.给了个pdf,打开是这玩意 2.盲猜flag是图片后面,右键直接删除图片试试. 答案出来了.

  6. CG-CTF Our 16bit wars

    一题纯看汇编的题 INT 21H, ah为0A时,是输入字符串到缓冲区DS:DX,DX+1地址存放着字符串长度 说明了长度为35 这里加密是右移3位异或左移5位, 告诉了我们加密后的字符串是什么,写个 ...

  7. 「CF1208G」 Polygons

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

  8. [刘阳Java]_MyBatis_其他方式来实现多表查询的操作_第9讲

    MyBatis其他方式来实现多表查询的操作 利用Java中的集合框架(List,Map) 其中List存储多个查询返回的记录 Map查询返回字段,同时记录表中一条数据 <?xml version ...

  9. jquery性能优化建议-上篇

    一.注意定义jQuery变量的时候添加var关键字这个不仅仅是jQuery,所有javascript开发过程中,都需要注意,请一定不要定义成如下:$loading = $('#loading'); / ...

  10. springboot-1-入门

    springboot-1-入门 1.springboot简介,背景 简化Spring应用开发的一个框架: 整个Spring技术栈的一个大整合: J2EE开发的一站式解决方案: 2.极简hellowor ...