一道阿里的java多线程题
2017-07-26 16:11
190 查看
public class MyStack { private List<String> list = new ArrayList<String>(); public synchronized void push(String value) { synchronized (this) { list.add(value); notify(); } } public synchronized String pop() throws InterruptedException { synchronized (this) { if (list.size() <= 0) { wait(); } return list.remove(list.size() - 1); } } }
case1:删除不存在的元素
假设现在有三个线程A、B、C,其中A用于添加元素,B、C用于删除元素。
某时刻,栈为空,
step1、线程B运行,获取锁,list.size()=0,进入wait(),wait状态下会释放当前锁
step2、线程A运行,获取锁,添加元素,执行list.add(value),此时list.size()=1,注意:在A执行notify()之前,线程C启动,发现其他线程已经拥有对象锁,因此进入阻塞状态,等待锁
step3、线程A执行notify(),试图唤醒等待中的线程B,但是但是但是,如果此时C获取了对象锁,那么将优先执行,那么C判断list.size()=1,直接删除元素,然后释放对象锁(疑惑:1.这里C是否可以优先获取对象锁,因为B已经在wait状态? 2.如果C能优先获取对象锁,那么如何保证C结束后B能顺利被唤醒?)
step4、wait状态下的B获取对象锁,直接执行list.remove(list.size()-1),发生错误!!!
解决办法: 使用可同步的数据结构来存放数据,比如LinkedBlockingQueue之类。由这些同步的数据结构来完成繁琐的同步操作。
case2:虚假唤醒
虚假唤醒就是一些obj.wait()会在除了obj.notify()和obj.notifyAll()的其他情况被唤醒,而此时是不应该唤醒的。
解决的办法是基于while来反复判断进入正常操作的临界条件是否满足: (将if换成while)
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}2015-08-13
相关文章推荐
- java-多线程-一道阿里面试题分析
- java-多线程-一道阿里面试题分析
- java一道多线程题,子线程循环10次,主线程接着循环100次,如此循环50次的问题
- 一道阿里多线程面试题分析
- 一道阿里多线程面试题分析
- 顺序打印ABC------java多线程的一道经典面试题
- 从java一道多线程题目想到
- 一道经典的Java多线程编程题
- 【java并发】一道多线程问题
- 关于网宿厦门研发中心笔试的一道PV操作题:利用java中的多线程实现生产者与消费者的同步问题
- java并发编程--一道经典多线程题的2种解法
- 一道经典的Java多线程编程题
- 【java并发】一道多线程问题
- 一道阿里多线程面试题的分析与应对
- java 多线程超详细总结——阿里大牛熬夜整理
- 实践JAVA wait(), notify(),sleep方法--一道多线程的面试题
- 一道java多线程笔试上机题
- 一道java多线程题
- java 一道多线程的题
- 一道java多线程题