2012-08-29 47 views
1

我正在写一个我有List的类。我从Runnable的运行方法实例化列表。如:线程列表的内存范围

public void sendEmailToLegalUsers() { 
    Log.info("JYM===================================="); 

    try { 
     new Runnable() { 

      public void run() { 
       userCns = new ArrayList<String>(); 
       recipients = new ArrayList<String>(); 

       ///other codes 
      } 
     };     
    } catch (Exception e) { 
     Log.info("Error occurred in LDAPSendMail: "+ e.getMessage()); 
    } 

    Log.info("END===================================="); 
} 

现在每次调用sendEmailToLegalUsers方法都会有一个新的线程。现在我想知道该列表的内存范围是否与类级别相关(如果它与类级别有关,并且如果说这个方法被调用了两次,那么线程1创建的列表将会发生什么情况一个线程2)或者当线程运行在他们自己的作用域中时,那么这个列表对于每个线程将有不同的范围。有没有机会在两个或多个线程之间混合列表数据?

回答

4

如果您对两个线程使用相同的Runnable类,那么会出现重叠。如果每个线程都有单独的new Runnable(),那么它们将是单独的列表实例,但是只有当列表定义为Runnable的本地时,才会这样。如果在呼叫类中定义了列表,那么当您第二次调用您的方法时,userCnsrecipients字段将被覆盖。

在你的情况,我没有看到任何线程被分叉。我看到的只是实例化Runnable。你确定你是不是要像做:

new Thread(new Runnable() { 
     public void run() { 
      // lists are local to the runnable 
      List<String> userCns = new ArrayList<String>(); 
      List<String> recipients = new ArrayList<String>(); 
      ///other codes 
     } 
    }).start(); 

在这种情况下,每个你打电话给你sendEmailToLegalUsers()方法的时候,一个新的Runnable将用新的列表来创建。

+0

非常感谢您的解释。 –

0

如果多个线程调用相同run(),是的,有错误结果的机会,因为列表是实例范围,并且两个线程都在同一列表上操作。

如果为每个线程创建新的Runnable(),那么它们将拥有自己的副本,并且它们不会更新每个其他数据。

4

您正在为每个线程创建一对新的列表。你也应该让它们成为局部变量,否则你可能会遇到线程安全问题,而不是列表中的列表,而是列表的引用。

new Thread(new Runnable() { 
    public void run() { 
     List<String> userCns = new ArrayList<String>(); 
     List<String> recipients = new ArrayList<String>(); 

     ///other codes 
    } 
}).start(); 

如果userCns或收件人是字段,它们可以在线程之间共享,因为该字段是共享的。

0

您正在创建一个新的Runnable,但没有对它进行任何操作 - 您当然不会创建一个新的Thread。

但是,如果您要将创建的Runnables传递给线程,则引用将被限制为Runnable实例。