1

我正在写一个我有一个列表的课程。我正在从 的 run 方法实例化列表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

4 回答 4

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都会使用新列表创建一个新方法。

于 2012-08-29T14:37:03.770 回答
4

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

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

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

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

于 2012-08-29T14:37:48.420 回答
0

如果多个线程调用相同run(),是的,有可能出现错误结果,因为列表是实例范围,并且两个线程都在同一个列表上运行。

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

于 2012-08-29T14:36:51.807 回答
0

你正在创建一个新的 Runnable,但没有对它做任何事情——你肯定不是在创建一个新的线程。

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

于 2012-08-29T14:39:12.473 回答