java并发之sleep与wait、notify与notifyAll的区别

线程对象与锁对象的概念

线程对象是线程类的实例对象,线程类通过继承Thread类或实现Runnable接口获得。通过重写run()方法并发执行程序代码,极大的提高了程序的执行速度。多个线程之间合作需要进行同步,而锁是实现线程同步的机制之一,基于万物皆对象的思想理念,锁也是一种对象,Java中所有的对象都可以被当做锁来使用。这句话非常重要,它解释了下文中所述的为何wait、notify、notifyAll是在object类实现的。

锁池和等待池的概念

锁池与等待池分别是不同线程状态的两种集合。

锁池
假设某对象锁当前被线程A所持有,而其他想持有该锁的线程就会先放进锁池中,待线程A释放所持有的锁时,锁池中线程可以竞争持有该锁。也即是说,锁池中的线程对象具备竞争锁的资格。

等待池
当锁对象调用wait方法时,则持有该对象锁的线程进入等待池中,进入等待池中的线程对象不具备持有锁的资格。

sleep与wait的区别

区分这三者的关键在于锁。
首先,wait(),notify(),notifyAll()都是object类的方法,可能你会疑问:既然wait()等方法是和线程相关的,为何不在线程类中实现呢?其实上文已经给出答案了,wait(),notify(),notifyAll()方法其实属于锁对象,而所有对象都可以当做锁来使用。wait()方法的意思是持有该锁对象的线程对象进入wait状态:释放锁,然后将当前线程放入等待池中。

而sleep()方法是在线程类中实现的,其调用者是线程对象。sleep()的作用是将当前线程暂停一定的时间,但在这期间并不释放锁。

这里写图片描述

notify与notifyAll的区别

notify()用于随机唤醒一个等待该锁对象的线程,notifyAll()用于唤醒所有等待该锁对象的线程。(被唤醒表示该线程具备了竞争锁的资格)也即是:notify()会在等待池中随机选择一个线程对象放入锁池中。而notifyAll会将所有等待该锁的线程放入锁池中。

发布了36 篇原创文章 · 获赞 85 · 访问量 38万+

猜你喜欢

转载自blog.csdn.net/u012719153/article/details/78915034
今日推荐