我结合了java中n个线程的结果
我需要写一个CSV文件,所以我需要点击web服务超过2k条记录(每次一次),所以我使用线程点击web服务 现在我在做下面的事情我结合了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
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-不是真的-您只需要多个生产者线程将数据送入队列,一个消费者线程将其取出。如何表示所有内容都已完成取决于您,使用线程池应该会有所帮助。