代码之家  ›  专栏  ›  技术社区  ›  Mehmed Andrew Lam

向SynchronizedMap和synchronized块添加或删除

  •  0
  • Mehmed Andrew Lam  · 技术社区  · 6 年前

    我正在使用AWS Android SDK将图像文件上传到S3 bucket。我在一个线程中执行裁剪操作,该线程在裁剪完成后开始传输图像文件。我将所有TransferObserver实例保存在映射中,定义和初始化如下:

    private Map<String, TransferObserver> transferObservers;
    
    A() {
        transferObservers = Collections.synchronizedMap(new LinkedHashMap<String, TransferObserver>());
    }
    
    public void add(Image image) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                // Cropping
                ...
                TransferObserver uploadObserver = transferUtility.upload(key, new File(localFilePath));
                uploadObserver.setTransferListener(new TransferListener() {
                photoTransferObservers.put(image.getPath(), uploadObserver);
            }
        }
    }
    

    可以删除图像,以便其在地图中的条目:

    public void deleteTransferRecord(String key) {
        transferObservers.remove(key);
    }
    

    还有一个函数返回上传的整个过程:

    private void notifyListeners() {
        int completedUploadCount = 0;
        for (TransferObserver transferObserver : transferObservers.values()) {
            if (transferObserver.getState() == TransferState.COMPLETED) {
                completedUploadCount++;
            }
        }
        ...
    }
    

    transferObservers . 我应该如何更新代码以防止任何并发问题?

    1 回复  |  直到 6 年前
        1
  •  0
  •   tom    6 年前

    你可以在上面同步 transferObservers 无论您在何处访问它(无论是添加、删除还是读取)。在那一点上你不需要 Collections.synchronizedMap .

    notifyListeners . 这样,移除或添加到转移观察者不会导致 ConcurrentModificationException 迭代时。

    private void notifyListeners() {
        int completedUploadCount = 0;
        List<TransferObserver> observers = new ArrayList<>(transferObservers.values());
        for (TransferObserver transferObserver : observers) {
            if (transferObserver.getState() == TransferState.COMPLETED) {
                completedUploadCount++;
            }
        }
        ...
    }