欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

sleep(),wait(),yield(),notify()

发布时间:2024/7/19 编程问答 67 豆豆
生活随笔 收集整理的这篇文章主要介绍了 sleep(),wait(),yield(),notify() 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

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控制权。

转载于:https://www.cnblogs.com/wuchaodzxx/p/5986765.html

总结

以上是生活随笔为你收集整理的sleep(),wait(),yield(),notify()的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。