java - 为什么我应该 "final"在多线程程序中共享变量

标签 java concurrency

我的问题是为什么我应该使用final来修饰变量list?它被匿名内部类的实例使用,没有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();  
  }
}

但是如果我使用普通类,那就没问题了。

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;  }
}

最佳答案

这与多线程无关。它在那里是因为您试图从匿名内部类的方法访问 list 。在这种情况下,Java 总是会标记一个错误。

在您的情况下,您将使用 new 关键字在此处创建 Runnable 的匿名实例。您尝试从 run 取消引用的所有内容都需要是 final

如果您对 Final 关键字的必要性感到好奇,您可以查看 Jon Skeet 的 exhaustive answer这对其进行了深入的解释。

要点是,当您创建匿名内部类的实例时,该类中使用的任何变量都会通过自动生成的构造函数复制其值,如果该变量可以被其余的构造函数修改,那么看起来会很奇怪方法,反之亦然。

关于java - 为什么我应该 "final"在多线程程序中共享变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17776785/

相关文章:

java - Servlet Faces Servlet 的错误 StandardWrapperValve[Faces Servlet] :PWC1406: Servlet. service() 引发异常

sql - 是否建议在 Oracle EBS 并发程序中提交一个 Commit?

c# - C# 中的原子读-修改-写

java - 为什么调用服务器上的 php 文件不起作用?

java - 将 sqlMapConfig 保留在 jar/classpath 之外

java - 生产者/消费者工作队列

java - 协调多个并发队列

java - java中的http负载生成器

java - Android usb主机与定制板的串行通信

java高效去重