sleep(),wait(),yield() 的区别

sleep方法和yield方法是Thread类的方法,wait方法是Object的方法。

sleep 方法使当前运行中的线程睡眼一段时间,进入不可运行状态,这段时间的长短是由程序设定的,不会释放锁标志。

wait方法调用后,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

yield 方法使当前线程让出CPU占有权,但让出的时间是不可设定的。yield()也不会释放锁标志。

yield()方法对应了如下操作: 先检测当前是否有相同优先级的线程处于同可运行状态,如有,则把 CPU 的占有权交给此线程,否则继续运行原来的线程。所以yield()方法称为"退让",它把运行机会让给了同等优先级的其他线程。

sleep方法允许较低优先级的线程获得运行机会,但yield()方法执行时,当前线程仍处在可运行状态,所以不可能让出较低优先级的线程些时获得CPU占有权。 在一个运行系统中,如果较高优先级的线程没有调用 sleep 方法,又没有受到 I/O阻塞,那么较低优先级线程只能等待所有较高优先级的线程运行结束,才有机会运行。

yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。所以yield()只能使同优先级的线程有执行的机会。

wait()与notify()的关系与应用

看以下代码

public class WaitTest {
public int flag=10;
public static void main(String[] args) {
WaitTest wait = new WaitTest(); new Thread(new Runnable(){
public void run(){
wait.method1();
}
}).start(); new Thread(new Runnable(){
public void run(){
wait.method2();
}
}).start();
}
public void method1(){
System.out.println("method 1 is running");
try{
synchronized(this){
System.out.println("method 1 is into lock");
while(flag>0){
this.wait();
System.out.println("method 1 get notify");
}
System.out.println("method 1 is out lock");
}
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("method 1 is end");
}
public void method2(){
System.out.println("method 2 is running");
while(flag>0){
try{
synchronized(this){
flag--;
this.notify();
}
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.println("method 2 is end");
}
}
输出:
method 1 is running
method 1 is into lock
method 2 is running
method 1 get notify
method 1 get notify
method 1 get notify
method 1 get notify
method 1 get notify
method 1 get notify
method 1 get notify
method 1 get notify
method 1 get notify
method 1 get notify
method 1 is out lock
method 1 is end
method 2 is end

上例中,线程1执行method1先获取对象锁,然后判断flag的值,如果flag>0,则wait等待,此时释放锁。因此线程2执行method2可以获取对象锁,并且每次在锁内执行flag--,然后执行notify()通知其他线程,接着释放锁。线程1获取notify信号后,先获取对象锁,然后沿着wait方法继续向下执行。

wait()方法与notify()必须要与synchronized(resource)一起使用。也就是wait与notify针对已经获取了resource锁的线程进行操作,从语法角度来说就是Obj.wait(),Obj.notify必须在synchronized(Obj){...}语句块内。从功能上来说wait()线程在获取对象锁后,主动释放CPU控制权,主动释放对象锁,同时本线程休眠。直到有其它线程调用对象的notify()唤醒该线程,才能继续获取对象锁,并继续执行。相应的notify()就是对对象锁的释放操作。

【因此,我们可以发现,wait和notify方法均可释放对象的锁,但wait同时释放CPU控制权,即它后面的代码停止执行,线程进入阻塞状态,而notify方法不立刻释放CPU控制权,而是在相应的synchronized(){}语句块执行结束,再自动释放锁。】

释放锁后,JVM会在等待resoure的线程中选取一线程,赋予其对象锁,唤醒线程,继续执行。这样就提供了在线程间同步、唤醒的操作。Thread.sleep()与Object.wait()二者都可以暂停当前线程,释放CPU控制权,主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制,而在同步块中的Thread.sleep()方法并不释放锁,仅释放CPU控制权。

sleep(),wait(),yield(),notify()的更多相关文章

  1. JAVA 线程状态以及synchronized,wait,sleep,yield,notify,notifyAll

    java线程存在以下几种状态: 1: 创建状态(New):线程被new出来,还未调用start 2: 就绪状态(Runnable):又称为可执行状态,调用线程的start方法后,线程处于就绪状态,,线 ...

  2. Java多线程Thread.yield(),thread.join(), Thread.sleep(200),Object.wait(),Object.notify(),Object.notifyAll()的区别

    Thread.yield(),在某个线程里调用Thread.yield(),会使这个线程由正在运行的running状态转变为等待cpu时间片的runable状态.join()是Thread类的一个非s ...

  3. java 笔记(5) —— 线程,yield,join

    一.线程各个状态与转换: 新建状态:用new语句创建的线程对象处于新建状态,此时它和其它的java对象一样,仅仅在堆中被分配了内存 .就绪状态:当一个线程创建了以后,其他的线程调用了它的start() ...

  4. Java线程sleep,yield,join,wait方法详解

    1.sleep() 当一个线程调用sleep方法后,他就会放弃cpu,转到阻塞队列,sleep(long millis)方法是Thread类中的静态方法,millis参数设定线程睡眠的时间,毫秒为单位 ...

  5. JAVA之旅(十五)——多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止

    JAVA之旅(十五)--多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止 我们接着多线程讲 一.生产者和消费者 什么是生产者和消费者?我们 ...

  6. 零基础学习java------day18------properties集合,多线程(线程和进程,多线程的实现,线程中的方法,线程的声明周期,线程安全问题,wait/notify.notifyAll,死锁,线程池),

    1.Properties集合 1.1 概述: Properties类表示了一个持久的属性集.Properties可保存在流中或从流中加载.属性列表中每个键及其对应值都是一个字符串 一个属性列表可包含另 ...

  7. ObjectMonitor,ObjectWaiter 实现wait(),notify()

    0.java对象锁监视器 在JVM的规范中,有这么一些话:“在JVM中,每个对象和类在逻辑上都是和一个监视器相关联的”“为了实现监视器的排他性监视能力,JVM为每一个对象和类都关联一个锁”“锁住了一个 ...

  8. 在JavaScript中实现yield,实用简洁实现方式。

    原题还是老赵的: http://blog.zhaojie.me/2010/06/code-for-fun-iterator-generator-yield-in-javascript.html 原以为 ...

  9. python中print,return和yield的区别

    def func1(): for i in range(1, 5): print i def func2(): for i in range(1, 5): return i def func3(): ...

随机推荐

  1. 我们比较常见的PHP实现openSug.js参数调试

    这是一款利PHP对百度搜索下拉框提示免费代码实现参数配置调试的程序源代码. 由想要对网站进行搜索下拉调试的站长朋友们进行方便.快速的效果演示,具体参考下面的PHP代码. 如何使用? 请新建一份PHP文 ...

  2. 随记181120Service Fabric问题

    https://github.com/Azure/service-fabric-issues/issues/1056 不能启动node one /five 问题

  3. 领扣-两数之和-Python实现

    领扣每日一题 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个 ...

  4. linux——Shell编程基础

    1. shell 脚本的执行方式 1.1 直接绝对路径执行 1.2 相对路径执行 首先进入到shell脚本所造的目录 PS:用./执行要增加x权限.用bash执行可以不增加x权限 1.3 在当前she ...

  5. PAT甲级 1004.Counting Leaves

    参考:https://blog.csdn.net/qq278672818/article/details/54915636 首先贴上我一开始的部分正确代码: #include<bits/stdc ...

  6. express-session deprecated undefined resave option; provide resave option app.js

    nodejs使用express-session报错 代码如下 app.use(session({ secret: 'hubwiz app', //secret的值建议使用随机字符串 cookie: { ...

  7. Hystrix使用

    Hystrix是Netflix开源的一款容错系统,能帮助使用者码出具备强大的容错能力和鲁棒性的程序.如果某程序或class要使用Hystrix,只需简单继承HystrixCommand/Hystrix ...

  8. Linux入门进阶第三天——软件安装管理(下)

    一.yum在线安装 之前的rpm包各种依赖性太强!安装复杂,yum的好处就来了: // yum 在redhat是付费服务 1.yum源文件 先进入到yum目录: 我们打开默认生效的Base包 2.光盘 ...

  9. rsync + inotify 数据实时同步

    一.rsync介绍 rsync英文全称为Remote synchronization,从软件的名称就可以看出来,Rsync具有可是本地和远程两台主机之间的数据快速复制同步镜像.远程备份的功能,这个功能 ...

  10. IBM X3650M4简单排错方法

    如果出问题了,首先看开机的那个地方的灯是否显示正常,有黄色的灯亮一般都不正常: 这种服务器带有一个错误指示板,只需要在电源开关那,如上图,把那个蓝色的按钮往里面按,就能把里面的一个板子抽出来,可以看到 ...