更新了问题..请检查问题的secodn部分


我需要建立一个书ID的主列表。我有多个线程任务,这些任务带来了书ID的子集。每个任务执行完成后,我需要将它们添加到书籍ID的超级列表中。因此,我计划将以下聚合器类实例传递给我的所有执行任务,并让它们调用updateBookIds()方法。为了确保其线程安全,我将addAll代码保留在同步块中。

有人可以建议与同步列表相同吗?我可以只说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;
    }
}


谢谢,
ish


  第二种方法


因此,在进行以下讨论之后,我目前计划采用以下方法。如果我在这里做错了任何事情,请告诉我:-

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);
        }
    }
}


谢谢,
ish

最佳答案

我可以只说Collections.newSynchronizedList并从所有线程任务中调用addAll到该列表吗?


如果您指的是Collections.synchronizedList,那么可以,可以正常工作。这将为您提供一个实现List接口的对象,其中该接口上的所有方法(包括addAll)都将被同步。

不过,请考虑坚持自己拥有的东西,因为它可以说是一种更清洁的设计。如果将原始的List传递给任务,则他们可以访问该接口上的所有方法,而他们真正需要知道的是有一个addAll方法。使用SynchronizedBookIdsAggregator可以使您的任务与设计对List接口的依赖脱开,并消除了他们调用addAll以外的东西的诱惑。

在这种情况下,我倾向于寻找某种Sink接口,但是当我需要它时似乎从来没有一个接口。

关于java - 实现同步的addAll到Java中的列表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9621998/

10-08 23:24