我需要在不同的线程中迭代String的ArrayList,我不需要添加或删除项目,只是为了迭代。
我该怎么做?
答案 0 :(得分:5)
在最基本的形式中,你会做这样的事情。但是你的问题似乎比你问我们的要多得多吗?
final List<Item> items = new ArrayList<Item>();
items.addAll(stuff);
new Thread(new Runnable() {
public void run() {
for (Item item: items) {
System.out.println(item);
}
}
}).start();
答案 1 :(得分:1)
您可能遇到的唯一问题是,阅读线程访问与发布者线程相同的数据。为此你需要以线程安全的方式将引用传递给另一个线程(即通过使用volatile
修饰符声明的字段,使用AtomicReference
或者通过任何其他方式传递读写器线程中的内存屏障方式,比如传递ReentrantLock
或synchronize
块。注意 - 您不需要在内部迭代同步。在阅读列表之前,只需通过内存屏障。
例如(ReentrantLock):
private final ReadWriteLock lock = new ReentrantReadWriteLock();
final Lock w = lock.writeLock();
w.lock();
try {
// modifications of the list
} finally {
w.unlock();
}
.................................
final Lock r = lock.readLock();
r.lock();
try {
// read-only operations on the list
// e.g. copy it to an array
} finally {
r.unlock();
}
// and iterate outside the lock
答案 2 :(得分:0)
Thread splashThread = new Thread() {
@Override
public void run() {
List<String> mylist = new ArrayList<String>();
mylist.add("I");
mylist.add("Am");
mylist.add("definitely");
mylist.add("becoming");
mylist.add("a");
mylist.add("better");
mylist.add("programmer");
Iterator<?> i1 = mylist.iterator();
while (i1.hasNext()) {
System.out.println(i1.next());
}
}
};
splashThread.start();
}