论坛首页 招聘求职论坛

关于多线程的一个面试题,欢迎大家来讨论

浏览 9692 次
精华帖 (0) :: 良好帖 (0) :: 隐藏帖 (18)
作者 正文
   发表时间:2011-01-30  
一个被锁的老帖
===========================================================================
下面的代码在绝大部分时间内都运行得很正常,请问在什么情况下会出现问题?问题的根源在哪里?
package com.heyongjin.test;

import java.util.LinkedList;

public class Stack {

	LinkedList list = new LinkedList();

	public synchronized void push(Object x) {
		synchronized (list) {
			list.addLast(x);
			notify();
		}
	}

	public synchronized Object pop() throws Exception {  
		synchronized (list) {
			if (list.size() <= 0) {
				wait();
			}
			return list.removeLast();
		}
	}
}


答:这里有可能会死锁:当外界调用pop(),但堆栈中没有元素,即list.size() <= 0,Stack进入停滞状态(wait())(注意此时list被锁定了 ,但Stack不会被锁定),此时外界仍然可以进入push()(因为wait()不会锁定Stack),但此时在push()中调用list.addLast()时,因为list 被锁定,所以无法调用。
==================================================================
答案又了,但是怎么修改程序才能避免死锁呢??
   发表时间:2011-01-31  
为什么方法已经同步了,还要再同步list呢?去掉其中一个即可
0 请登录后投票
   发表时间:2011-01-31  
楼上正解,类外线程锁this,类内线程锁list
0 请登录后投票
   发表时间:2011-02-03  
list都空了,为什么还要wait?
0 请登录后投票
   发表时间:2011-02-03  
whiletrue 写道
list都空了,为什么还要wait?

同问
0 请登录后投票
   发表时间:2011-02-04  
一个丑陋的类
0 请登录后投票
   发表时间:2011-02-05   最后修改:2011-02-05
Thinking in java 好像有,是wait和notify那一节吧
package com.heyongjin.test;

import java.util.LinkedList;

public class Stack {

	LinkedList list = new LinkedList();

	public void push(Object x) {
		synchronized (list) {
			list.addLast(x);
			list.notifyAll();
		}
	}

	public Object pop() throws Exception {  
		synchronized (list) {
			while(list.size() <= 0) {
				list.wait();
			}
			return list.removeLast();
		}
	}
}


不过用while会多判断一次吧
这样也可以
public Object pop() throws Exception {  
	synchronized (list) {
                Object result= null;
		if(list.size() >0) {
		     result= list.removeLast();

		}else{
		     list.wait();
                }
                return result;
	}
}



0 请登录后投票
   发表时间:2011-02-06  
把空的判断挪到锁定对象的代码外面来
public synchronized Object pop() throws Exception { 
       if (list.size() <= 0) {   
                wait();   
       } else {    
       synchronized (list) {           
            return list.removeLast();   
       }   
       }
} 

0 请登录后投票
   发表时间:2011-02-08  
双锁......
有两个锁对像时就有可能死锁

把锁对像变成同一个就可以避免双锁.
0 请登录后投票
   发表时间:2011-02-09  
生活小丑 写道
whiletrue 写道
list都空了,为什么还要wait?

同问

应该是pop方法的目的是要返回一个非空的元素,所以空的时候就要等待。
0 请登录后投票
论坛首页 招聘求职版

跳转论坛:
Global site tag (gtag.js) - Google Analytics