多线程循环同步数组列表



我已经实现了一个应用程序,将文件从服务器机器FTP到客户端机器

for(String sourceFolder : foldersPaths){
  transferFolder(channelSftp,SFTPWORKINGDIR+sourceFolder,
                          DESWORKINGDIR+sourceFolder.replace("/","\"));
}

这段代码遍历字符串的 ArrayList 具有我需要传输的每个文件的源路径。我正在考虑利用带宽并同时为不同的文件启动多个传输。

如何创建同时执行"传输文件夹"方法的不同线程。是否可以安全,以便同一项目不会在不同的线程中循环两次。

谢谢

你可以有一个 ArrayBlockingQueue 来保存你的 URI,并让它安全地在池中的线程之间共享以执行。

    Set<String> submitted = Collections.synchronizedSet(new HashSet<String>());
    ExecutorService executorService = Executors.newFixedThreadPool(10); // how many threads to work with it
    for(final String sourceFolder : foldersPaths){
        if(! submitted.contains(sourceFolder)) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    transferFolder(...); // your method invoked here
                }
            };
            if (submitted.add(sourceFolder)) {
                executorService.submit(runnable);
            }
        }
    }
    executorService.shutdown();

问题不在于循环,而在于突变。如果你的List是不可变的,你可以根据需要从中读取尽可能多的Thread

但是,如果要从此List中删除/添加,则需要执行一些同步,或者必须使用并发数据结构。后者是我推荐的。对于您的情况,CopyOnWriteArrayList可能会解决问题。

如果您需要类似队列的数据结构,则可以使用例如LinkedBlockingQueue

方法 1 :

队列数据结构最适合此操作。从队列中获取文件时获取锁,然后在完成后释放锁。应使用相同的对象来授予跨所有线程的队列的访问权限。

while(!queue.isEmpty())
{
  synchronized(lockingObject)   /// Get the lock for mutual access to Queue
  {
     String file = queue.dequeue();
  }
 // lock is released
}

最新更新