Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在java中处理多线程时出现的问题(使用ThreadLocal)_Java_Multithreading - Fatal编程技术网

在java中处理多线程时出现的问题(使用ThreadLocal)

在java中处理多线程时出现的问题(使用ThreadLocal),java,multithreading,Java,Multithreading,我在java中使用多线程时遇到了一些问题。我是一名学生,java初学者,只是为了娱乐目的而开发它(抱歉语法不好,英语不是我的第一语言) 我正在做一个小型的个人下载程序,最多可以同时下载5次。每次下载都由不同的线程处理(不是普通线程,只是swingworker,我也使用它来避免UI冻结) 此方法工作正常(它下载一个文件,然后按预期将其保存到硬盘中)。但是当我想同时进行两次(或更多)下载时,问题就来了。考虑我同时下载两个文件,文件A < /强>和文件B。当我开始下载A时,字符串路径和名称根据文件A获

我在java中使用多线程时遇到了一些问题。我是一名学生,java初学者,只是为了娱乐目的而开发它(抱歉语法不好,英语不是我的第一语言)

我正在做一个小型的个人下载程序,最多可以同时下载5次。每次下载都由不同的线程处理(不是普通线程,只是swingworker,我也使用它来避免UI冻结)

此方法工作正常(它下载一个文件,然后按预期将其保存到硬盘中)。但是当我想同时进行两次(或更多)下载时,问题就来了。考虑我同时下载两个文件,<强>文件A < /强>和<强>文件B。当我开始下载A时,字符串
路径
名称
根据文件A获取其值,都正常。然后,我开始下载B,然后将A中先前存储的值替换为B对应的值。因此,当下载A完成时,文件名与下载B完成时B应具有的文件名相同。 继续,我需要相同变量的不同ì常量,它将包含不同的独立值

我开始研究这个话题,并引出了
ThreadLocal
变量。这种类型的变量应该在每个正在运行的线程中更改,这正是我所需要的。 我试图在我的代码中实现这一点

   public static String PATH;                   //File path
   public static String NAME;                   //File name

   public ThreadLocal<String> TL_PATH =  new ThreadLocal<String>();
   public ThreadLocal<String> TL_NAME =  new ThreadLocal<String>();

   public void download() { 
   //Try to set ThreadLocal to PATH and NAME variables.
       TL_NAME.set(NAME);
       TL_PATH.set(PATH);

   //download code... 

   }
公共静态字符串路径//文件路径
公共静态字符串名//文件名
public ThreadLocal TL_PATH=new ThreadLocal();
public ThreadLocal TL_NAME=new ThreadLocal();
public void download(){
//尝试将ThreadLocal设置为路径和名称变量。
TL_NAME.set(名称);
TL_PATH.set(路径);
//下载代码。。。
}
一旦我这样做了,一切都是一样的。我的代码出了什么问题?(在任何情况下都不会抛出异常,正如我之前解释的)

您做错了 您应该实现
Runnable
,并让它使用url和下载路径

使用池中的
ExecutorService
设置为
5
线程

管理实现
Runnable
的类的各个实例

以下是一个例子: 读者练习:
是一个更合适的解决方案,但它更复杂一些,最好使用
Callable
而不是
Runnable
。特别是对于像这样的批处理。但我这里有其他答案的例子,我不想再重复这个解决方案。

目前对我来说相当棘手和复杂。我会看看能不能多读一点。我的代码有很多类,我不知道我可以在其中的哪个类中实现它。不过,谢谢你的回答。现在我知道从哪里开始了。
   public static String PATH;                   //File path
   public static String NAME;                   //File name

   public ThreadLocal<String> TL_PATH =  new ThreadLocal<String>();
   public ThreadLocal<String> TL_NAME =  new ThreadLocal<String>();

   public void download() { 
   //Try to set ThreadLocal to PATH and NAME variables.
       TL_NAME.set(NAME);
       TL_PATH.set(PATH);

   //download code... 

   }
import javax.annotation.Nonnull;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Q24591731
{
    private static final ExecutorService EXECUTOR_SERVICE;

    static
    {
        EXECUTOR_SERVICE = Executors.newFixedThreadPool(5);
    }

    public static void main(final String[] args)
    {
        final Download d1;
        try { d1 = new Download(new URL("www.someurl.to.download.com"), new File("dest/file/name")); }
        catch (MalformedURLException e) { throw new RuntimeException(e); }
        // create as many downloads as you need how ever you want.
        EXECUTOR_SERVICE.submit(d1);
        // when all are submitted
        EXECUTOR_SERVICE.shutdown();
        try
        {
            EXECUTOR_SERVICE.awaitTermination(1, TimeUnit.MINUTES);
        }
        catch (InterruptedException e)
        {
            System.exit(1);
        }

    }

    public static class Download implements Runnable
    {
        private final URL url;
        private final File dest;

        public Download(@Nonnull final URL url, @Nonnull final File dest)
        {
            this.url = url;
            this.dest = dest;
        }

        @Override
        public void run()
        {
            // download the file and write it to disk
        }
    }
}