我的问题是为什么我应该使用final来装饰变量,列表?它由匿名内部类的实例使用而不是final,它不会编译.
代码如下所示:
public class TwoThreadsOneListCurrModi
{
public static void main(String[] args)
{
final List<String> list = Collections.synchronizedList(new ArrayList<String>());
for (int i =0 ; i<20;i++)
list.add(String.valueOf(i));
Thread t1 = new Thread(new Runnable(){
@Override
public void run()
{
synchronize(list) {
System.out.println("size of list:" +list.size());
}
}
});
t1.start();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用普通课,那很好.
public class TwoThreadsOneListCurrModi2
{
public static void main(String[] args)
{
final List<String> list = Collections.synchronizedList(new ArrayList<String>());
initialize list;
Thread t1 = new WorkThread(list);
Thread t2 = new WorkThread(list);
t1.start();
t2.start();
}
}
class WorkThread extends Thread{
List<String> list;
public void run(){
do sth with list and synchronize block on list
}
Work1(List<String> list)
{ this.list = list; }
}
Run Code Online (Sandbox Code Playgroud)
Ada*_*old 11
这与多线程无关.它就在那里,因为你试图list从一个匿名的内部类方法访问.在这种情况下,Java将始终签署错误.
在您的情况下,您Runnable使用new关键字创建此处的匿名实例.你想要取消引用的一切都run需要final.
如果您对最终关键词的必要性感到好奇,可以查看Jon Skeet的详尽答案,深入解释.
关键在于,当您创建匿名内部类的实例时,在该类中使用的任何变量都会通过自动生成的构造函数复制它们的值,如果该变量可以被该方法的其余部分修改,则看起来很奇怪反之亦然.