您的位置:首页 > 编程语言 > Java开发

一道阿里的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 多线程