是不是 Vector lv=null; //Make a copy of the vctor in case someone //adds a listener while we're //calling listeners; synchronized(this){ lv=(Vector)actionListeners.clone(); } for(int i=0;i<lv.size();i++){ ActionListener al=(ActionListener)lv.elementAt(i); al.actionPerformed(a); }我认为不会死锁, 就像注释所说,复制是为了防止在这一过程中(其实也就是在下面的for里)有新的 ActionListener被加入actionListeners, 而在那个for 中所做的并不是改变那些actionListener,而是执行他们,而且这个例子本身并不是Thread(虽然它出现在多线程一章),我在整个程序里也没有找到什么地方会等待那些ActionListener符合某种条件的语句。况且,即使它是一个Thread,对actionListeners的每个元素进行clone,也不能保证那些ActionListener对自己执行的是深层clone, 比如 class A implements ActionListener,Cloneable{ Object importantThingToTheThread; ..... public void actionPerformed(ActionEvent e).... public Object clone(){ return super.clone(); //importantThingToTheThread not cloned here! } }
在教clone的地方,他用深层clone让你了解真正完整的clone需要将其内部所有的元素都clone一遍,否则其内部元素仍是原来的,而不是clone的新版本。
在多线程中的重点就不是什么clone了,而是如何同步,防止死锁等。
你给人的感觉就是一个小学生问老师
为什么
(1+2+99+98)*2=200*2=400,
上次不是
1+2+99+98=(1+99)+ (2+98)=200;
这次也应该是
(1+2+99+98)*2=[(1+99)+ (2+98)]*2=200*2=400,
老师,书上这么写好像错了!
废话,我当然知道。我是觉得好像这样不能防止死锁,它们操作的是同样的对象啊?
那你给我解释一下为什么如此clone就能够防止死锁?
Vector lv=null;
//Make a copy of the vctor in case someone
//adds a listener while we're
//calling listeners;
synchronized(this){
lv=(Vector)actionListeners.clone();
}
for(int i=0;i<lv.size();i++){
ActionListener al=(ActionListener)lv.elementAt(i);
al.actionPerformed(a);
}我认为不会死锁,
就像注释所说,复制是为了防止在这一过程中(其实也就是在下面的for里)有新的
ActionListener被加入actionListeners, 而在那个for 中所做的并不是改变那些actionListener,而是执行他们,而且这个例子本身并不是Thread(虽然它出现在多线程一章),我在整个程序里也没有找到什么地方会等待那些ActionListener符合某种条件的语句。况且,即使它是一个Thread,对actionListeners的每个元素进行clone,也不能保证那些ActionListener对自己执行的是深层clone,
比如
class A implements ActionListener,Cloneable{
Object importantThingToTheThread;
.....
public void actionPerformed(ActionEvent e)....
public Object clone(){
return super.clone(); //importantThingToTheThread not cloned here!
}
}
这是一个Canvas,作者的目的是让一个Canvas具有ActionListener的功能,
你已经删除了一个ActionListener,还会去想它吗?不要告诉我你不知道ActionListener是什么