论坛首页 招聘求职论坛

以前为公司出的一道面试题,有点偏,有兴趣的可以试试

浏览 34250 次
精华帖 (0) :: 良好帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-05-19  
有如下代码:
class Stack
{   
    LinkedList list = new LinkedList();

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

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

}

这是一个简单的栈实现代码,问这个实现有没有问题?如果有,请举例说明。(关键字:Thread)
   发表时间:2007-05-19  
synchronized(x), y.wait(), z.notify()
必须x==y;y==z;

把x想象为有钩子的东西
x.wait()=加入x的等待队列中,并把当前线程挂起
x.notify()=提醒x的等待队列某个等待线程

还有个notifyAll()。。。
0 请登录后投票
   发表时间:2007-05-19  
To:Qieqie
如果我没有理解错你的意思的话,你应该是认为Stack代码里的wait和notify使用了不同的监视器。你对wait和notify的理解是对的,不过还不能说明这个Stack的问题出在哪里。如果我误解你意思的话请指正。

可以说明的是这个Stack写的不会有语法错误,运行期也不会抛IllegalMonitorStateException。
0 请登录后投票
   发表时间:2007-05-19  
因为你在方法前加了synchronized ,相当于synchronized (this),所以运行不会错  呵呵蛮有意思的

同时,每次wait()等待后被唤醒,还得需要判断继续执行的条件是否满足了
不满足就得继续wait
可以把if改为while保证这个问题

再认真点 既然你在方法前面做了synchronized ,而且wait和notify也是对this进行操作
这时候已经能保证了对list操作的同步了 所以synchronized(list) 这条语句可以不用了
0 请登录后投票
   发表时间:2007-05-20  
应该怎么改呢?
0 请登录后投票
   发表时间:2007-05-20  
这个应用程序问题非常大.......
class Stack  
{     
   //防止外部直接调用
   private LinkedList list = new LinkedList();  
 
  //只用一个synchronized既可以
    public synchronized void push(Object x)  
    {     
           list.addLast( x );
        //在这里一定要用notifyAll(),通知 所有等待的线程  
            notifyAll();     
    }  
 
    public synchronized Object pop()  
    {    
    //  这里一定是while,而不能为if,这个问题在java programming language一书中,给出了专门注释
          while( list.size() <= 0 )  
                wait();  
            return list.removeLast();  
        }  
    }  
 
}  
0 请登录后投票
   发表时间:2007-05-20  
好象还没有人告诉我这个程序的问题出在哪里,会导致什么样的结果。我们在改程序前也应该先搞清楚这两个问题的对吧。

这里不是考你如何改这个程序,而是考你对线程MONITOR的理解,可以说你们都没有讲到点子上(不是把if改成while这么简单的)。首先要说明楼上修改是对的,不过我们更关心的是这个错误的本质是什么,这是一个非常特殊的个案,所以修改也简单,但在真正错综复杂的项目代码里如何避免同样问题的代码出现,这就不简单了,需要你理解这个问题的根源是什么。
0 请登录后投票
   发表时间:2007-05-20  
这样吧,为了不干扰大家的视听,现在修改一下代码,用while替换掉if:
class Stack   
{      
    LinkedList list = new LinkedList();   
  
    public synchronized void push(Object x)   
    {   synchronized(list)   
        {   list.addLast( x );   
            notify();   
        }   
    }   
  
    public synchronized Object pop()   
    {   synchronized(list)   
        {   while( list.size() <= 0 )   
                wait();   
            return list.removeLast();   
        }   
    }   
  
}
0 请登录后投票
   发表时间:2007-05-20  
Michael.Scofield 写道
关键是看对synchronized 的理解,我们先看看如何调用Stack
Stack stack=new Stack();
stack.push(object);
stack.pop();
……
synchronized(list)这是对象同步,在多线程环境中对象的同步是对同一个对象才有效的,显然在以上的程序中是new LinkedList ,所以这里的synchronized(list)是没有效果


如果某人将这个Stack作为一个单实例来用呢?在这个个案里synchronized(this)和synchronized(list)是一样的,synchronized(this)起作用则synchronized(list)也会同时起作用。
0 请登录后投票
   发表时间:2007-05-20  
同步这东西可以参考池。。。
0 请登录后投票
论坛首页 招聘求职版

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