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中n个线程的结果_Java_Multithreading_Static - Fatal编程技术网

我结合了java中n个线程的结果

我结合了java中n个线程的结果,java,multithreading,static,Java,Multithreading,Static,我需要写一个CSV文件,所以我需要点击web服务超过2k条记录(每次一次),所以我使用线程点击web服务 现在我在做下面的事情 for(String customer: Customers) { Thread th=new Thread(new TaskFile(customer)) th.start(); } **static Map=TaskFile.map iterate map...** } public class TaskFile implements runnable { p

我需要写一个CSV文件,所以我需要点击web服务超过2k条记录(每次一次),所以我使用线程点击web服务

现在我在做下面的事情

for(String customer: Customers)
{
 Thread th=new Thread(new TaskFile(customer))
th.start();

}
**static Map=TaskFile.map
iterate map...**
}
public class TaskFile implements runnable
{

private String customer;
public static Map map=new HashMap();

public taskFile(String customer)
{
this.customer=customer;
}

 public void run()
 {
  websrivce call..
  map.put(customer,result)
}


}
所以我使用静态映射来合并所有值的结果,但是是否有其他方法来合并所有线程结果。因为静态是由jvm加载的

我将来可能有10万张唱片。
好的,我有我自己的框架来处理这个线程,由于安全问题,我不能分享。静态呢……这只是一个例子。因此,请帮助我进行静态映射并对结果进行分类

我不希望一次生成10万个线程-您可能很容易就将web服务压得喘不过气来。与其使用ThreadPoolExecutor生成任务,还不如使用方法等待结果。这样,您就可以轻松地调整并发请求的数量


如果您只想将结果添加到CSV文件,我会添加一个中心,其中web服务客户端线程是生产者,CSV编写线程是消费者。通过这种方式,您可以巧妙地将访问web服务与写入文件分离,从而最大限度地减少过程中的延迟。

对于这种环境,最简单的解决方法是使用
队列

创建一个队列,创建任意数量的线程(推荐
ThreadPools
,但这是您的选择),并告诉每个线程有关队列的信息。然后,每个线程将项目按自己喜欢的方式推送到队列上

然后有一个消费者从队列中读取所有结果

    Queue<Type> queue = new LinkedBlockingQueue<>();
    for (String customer : Customers) {
        Thread t = new Thread(new Producer(queue, customer));
        t.start();
    }
    Thread consumer = new Thread(new Consumer(queue));
Queue Queue=新建LinkedBlockingQueue();
for(字符串客户:客户){
线程t=新线程(新生产者(队列、客户));
t、 start();
}
线程使用者=新线程(新使用者(队列));

首先,您需要使用线程安全映射,如

其次,您不需要静态映射,您可以将构造函数中的映射传递给每个
可运行的

public class TaskFile implements runnable
{

    private String customer;
    private Map map;

    public taskFile(String customer, Map map)
    {
        this.customer=customer;
        this.map = map;
    }

    public void run()
    {
        //  websrivce call..
        map.put(customer,result)
    }
}

// ...
Map map = new ConcurrentHashMap();
for(String customer: Customers)
{
    Thread th=new Thread(new TaskFile(customer, map))
    th.start();

}
请注意,我忽略了泛型,因为您没有指定要使用的类型,但应该明确使用泛型


此外,正如@Marko Topolnik所说,为每一行启动一个线程是一种过分的做法。

这看起来像是为每个客户记录创建一个线程,这可能会对您的系统造成不良影响(作为参考,请尝试查看任务管理器,了解其他进程要使用多少线程)

我在这里的方法是将客户记录添加到某种形式的(并发!)队列对象中,然后创建一些可运行的对象,其任务是尽可能快地从该队列中拉出,处理记录,循环,直到队列为空,在该点终止

我不确定这种方法是否比单线程处理记录更能提高性能,但它是一种更明智的多线程处理方法。

  • 我认为您担心的是,如果部署了应用程序并且存在多个请求,那么您的静态映射似乎不适用(因为两个作业结果将放在同一个静态映射中!)
  • 在本例中,我建议为每个作业创建一个hashmap,并将其传递给线程的构造函数。您可以删除映射的静态线程,从而使一个作业的所有线程引用存储结果的单个映射

    Map<> map = new HashMap<>();
    for(String customer: Customers)
    {
        Thread th=new Thread(new TaskFile(customer,map ));
        th.start();
    }
    
    Map Map=newhashmap();
    for(字符串客户:客户)
    {
    Thread th=新线程(新任务文件(客户,映射));
    th.start();
    }
    
  • 完成后在map上迭代,因为引用被保留并且结果是可访问的

但是,正如其他人提到的,在你的方法中有很多可能的漏洞!一定要注意。

每CSV行启动一个线程肯定是错误的。使用具有有限线程池的Executor服务(可能不超过10个)。好的,我有自己的框架来处理这个线程,由于安全问题,我无法共享它。静态呢?如何合并所有结果?同意。让我试试buddyCollection。syncronizedMap(新Hashmap())是否可以,因为我已经使用了它。使用ConcurrentHashMap编程更容易,因为你不需要用synchronized block来包装它的用法。我需要把运行线程的主类中的值合并到不在runnable类中的主类中。那么我怎样才能得到映射的输出呢,就像我在消费者线程之后需要做的。它将如何提供所有results@Ranjithkumar-不是真的-您只需要多个生产者线程将数据送入队列,一个消费者线程将其取出。如何表示所有内容都已完成取决于您,使用线程池应该会有所帮助。