我正在写一个我有List的课程。我正在从Runnable
的run方法实例化列表。为:
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)或当线程在它们自己的范围内运行时,列表将为每个线程具有不同的范围。有没有机会在两个或多个线程之间混合列表数据?
答案 0 :(得分:4)
如果您对两个线程使用相同的Runnable
类,那么是,将会有重叠。如果你的每个线程都有一个单独的new Runnable()
,那么它们将是单独的列表实例但是这只有在列表被定义为Runnable
的本地时才。如果列表是在调用类中定义的,那么第二次调用方法时,userCns
和recipients
字段将被覆盖。
在你的情况下,我看不到任何线程被分叉。我只看到你实例化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
。
答案 1 :(得分:4)
您正在为每个线程创建一对新列表。您还应该使它们成为局部变量,否则您可能会遇到线程安全问题,而不是列表,而是列表的引用。
new Thread(new Runnable() {
public void run() {
List<String> userCns = new ArrayList<String>();
List<String> recipients = new ArrayList<String>();
///other codes
}
}).start();
如果userCns或收件人是字段,则可以在线程之间共享它们,因为该字段是共享的。
答案 2 :(得分:0)
如果多个线程调用相同的run()
,则可能会出现错误的结果,因为list是实例范围,并且两个线程都在同一个列表上运行。
如果为每个线程创建新的Runnable(),那么它们将拥有自己的副本,并且不会相互更新数据。
答案 3 :(得分:0)
你正在创建一个新的Runnable,但没有用它做任何事情 - 你肯定没有创建一个新的线程。
但是,如果要将创建的Runnables传递给线程,则引用将限制为Runnable实例。