当年面试阿里巴巴时要求手写出代码!
看完这篇文章,你也会写!
wait和notify
Java中最经典的wait和notify。wait操作可以让一个线程阻塞,等待某个条件发生从而唤醒自己。notify可以唤醒一个阻塞在某条件上的线程。
wait用法:
synchronized(sharedMonitor) { while(someCondition) { // 必须用一个检查感兴趣的条件的while循环来包围wait() sharedMonitor.wait(); // 因为wait方法的返回不一定意味着someCondition变成true了(可以假装返回;当someCondition中有多个条件谓词时,可能某个线程调用了notify使得某一个wait返回了)。 }}
notify用法:
synchronized(sharedMonitor) { sharedMonitor.notify();}
生产者消费者问题
如何让两个线程交替输出1和2?
注意,使用条件队列,wait和notify来进行线程间的同步,需要注意到条件队列、条件谓词和锁之间的三元关系。条件队列比如同步容器,条件谓词即状态,如果某项工作完成了,则设置一个状态表示完成了,锁则是条件队列的锁,即同步容器的锁。
话不多说,上代码!
输出“1”的线程
按照本文开始介绍的“wait用法”和“notify用法”,我们先新创建一个线程,获取lockOne对象上的锁,while中设置一个条件flag,当flag不满足条件时,让当前线程进入wait阻塞状态,等待唤醒。
如果当前线程被唤醒了,说明另一个线程输出了“2”,则本线程该开始输出“1”了。所以输出1之后,把标志位flag设置一下,让对面线程能够接着输出“2”。
输出“2”的线程
按照本文开始介绍的“wait用法”和“notify用法”,我们接着创建一个线程,获取同一个lockOne对象上的锁,while中设置上面那个线程相反的flag条件,即当对面线程进入阻塞状态时,表明我们这个线程该唤醒了,要输出“2”了。
来,启动一下看看:
最后输出结果如我们所愿,交替输出了“1”和“2”。