多线程循环同步ArrayList

时间:2014-02-25 16:24:55

标签: java multithreading

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

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

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

如何同时创建执行“transferFolder”方法的不同线程。它是否安全,以便相同的项目不会在不同的线程中循环两次。

谢谢

4 个答案:

答案 0 :(得分:2)

您可以拥有ArrayBlockingQueue来保存您的URI,并将其安全地在池中的线​​程中共享到execute

答案 1 :(得分:1)

问题不是循环而是变异。如果您的List是不可变的,那么您可以根据需要获得尽可能多的Thread个读数。

如果要删除/添加到此List但是需要进行同步,则必须使用并发数据结构。后者是我推荐的那个。对于您的情况,CopyOnWriteArrayList可以解决问题。

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

答案 2 :(得分:1)

方法1:

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

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

答案 3 :(得分:1)

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