Updated the question.. please check secodn part of question
我需要建立一个图书 ID 的主列表。我有多个线程任务,可以调出一部分书 ID。一旦每个任务执行完成,我就需要将它们添加到 book id 的 super 列表中。因此,我计划将下面的聚合器类实例传递给我的所有执行任务,并让它们调用 updateBookIds() 方法。为了确保线程安全,我将 addAll 代码保存在同步块(synchronized block)中。
任何人都可以建议这与同步列表相同吗?我可以只说 Collections.newSynchronizedList 并从所有线程任务中调用 addAll 到该列表吗?请澄清。
public class SynchronizedBookIdsAggregator {
private List<String> bookIds;
public SynchronizedBookIdsAggregator(){
bookIds = new ArrayList<String>();
}
public void updateBookIds(List<String> ids){
synchronized (this) {
bookIds.addAll(ids);
}
}
public List<String> getBookIds() {
return bookIds;
}
public void setBookIds(List<String> bookIds) {
this.bookIds = bookIds;
}
}
谢谢, 哈里什
Second Approach
经过以下讨论,我目前正计划采用以下方法。如果我在这里做错了什么,请告诉我:-
public class BooksManager{
private static Logger logger = LoggerFactory.getLogger();
private List<String> fetchMasterListOfBookIds(){
List<String> masterBookIds = Collections.synchronizedList(new ArrayList<String>());
List<String> libraryCodes = getAllLibraries();
ExecutorService libraryBookIdsExecutor = Executors.newFixedThreadPool(BookManagerConstants.LIBRARY_BOOK_IDS_EXECUTOR_POOL_SIZE);
for(String libraryCode : libraryCodes){
LibraryBookIdsCollectionTask libraryTask = new LibraryBookIdsCollectionTask(libraryCode, masterBookIds);
libraryBookIdsExecutor.execute(libraryTask);
}
libraryBookIdsExecutor.shutdown();
//Now the fetching of master list is complete.
//So I will just continue my processing of the master list
}
}
public class LibraryBookIdsCollectionTask implements Runnable {
private String libraryCode;
private List<String> masterBookIds;
public LibraryBookIdsCollectionTask(String libraryCode,List<String> masterBookIds){
this.libraryCode = libraryCode;
this.masterBookIds = masterBookIds;
}
public void run(){
List<String> bookids = new ArrayList<String>();//TODO get this list from iconnect call
synchronized (masterBookIds) {
masterBookIds.addAll(bookids);
}
}
}
谢谢, 哈里什
最佳答案
Can I just say
Collections.newSynchronizedList
and calladdAll
to that list from all thread tasks?
如果您指的是 Collections.synchronizedList
,那么是的,那可以正常工作。这将为您提供一个实现 List
接口(interface)的对象,其中来自该接口(interface)的所有方法都是同步的,包括 addAll
。
尽管如此,请考虑坚持使用现有的设计,因为它可以说是一种更简洁的设计。如果您将原始 List
传递给您的任务,那么它们就可以访问该接口(interface)上的所有方法,而它们真正需要知道的只是有一个 addAll
方法.使用您的 SynchronizedBookIdsAggregator
可以使您的任务与对 List
接口(interface)的设计依赖性分离,并消除它们调用 addAll
以外的东西的诱惑。
在这种情况下,我倾向于寻找某种类型的 Sink
接口(interface),但是当我需要它时似乎从来没有出现过...
关于java - 在java中实现同步addAll到列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9621998/