习惯是养成的,那为什么不养成好习惯呢?
最近工作中遇到了一些并发编程的知识,想着抽时间将这一块整理下,想到就做,今天就开始^_^。
如题,今天来看下Object的wait/notify/notifyAll方法。
我们知道Java是个单继承的语言,所有的类都默认继承Object,那这3个方法也就是所有的类都有的方法。
0.Object方法概览
这几个方法都是native方法,非Java语言实现。
1.What-这几个方法是干什么用的?
在多线程并发的场景下,各个线程间如果想通信,该怎么办呢?
当然,有很多方法,以后慢慢讲,wait/notify/notifyAll就是其中的一种。
2.How-这几个方法怎么使用呢?
先找一个场景,比如公司有一台打印机,大家都需要打印资料,但是打印机在某个时间段,只能供一个人使用,其他人只能等待。当打印完后,可以通知大家,让下一位使用。用代码怎么实现呢?
1)先定义一个Printer类,属性used表示当前打印机的状态
2)再定义一个通知类,负责通知大家打印机的状态
3)最后再定义一个Waiter类,表示等待使用打印机的人
咱们写个测试程序来跑下这段代码。
代码概述:先设置打印机的状态为使用中,NotifyWaiter在休眠10s后,将打印机状态设置为空闲,然后通知大家,这里使用的是notify(),如果有多个等待者的话,只能有一个获取到这个通知;如果想让大家都获取到通知,可以使用notifyAll()。我们设置了3个Waiter,但使用的是notify(), 所以只有一个waiter获取到了通知,这里是waiter-2获取到了,多运行几次,可能是waiter-1,也可能是waiter-3。
3.Why-为什么这样使用,有哪些注意点?
细心的你可能会发现,在使用notify()/wait()的时候,都是在synchronized同步块中,为什么?
答:多线程编程是个比较难的话题,难在哪儿?难在多个线程并发执行?不是,难在并发执行的多个线程之间的数据共享和状态交互。想想也是,如果多个并发线程都大路朝天,各走一边,没有交互,并发编程还难么,不要太容易啊。可以不是。。。,wait()方法强调释放锁,也就意味着执行wait()方法前已经获得了锁,同步块就保证了,在执行wait()前获得了锁。notify()通知大家去领锁,如果notify()没有锁,通知大家领什么呢?所以通知之前必须保证已经获取了锁。
今天先到这儿,明天继续^_^。