在Java中使用多线程缩短程序时间

在Java中使用多线程缩短程序时间,java,multithreading,concurrency,Java,Multithreading,Concurrency,我没有多少制作多线程应用程序的经验,但我觉得我的程序正处于一个可以从多线程中获益的阶段。我正在做一个更大规模的项目,涉及使用分类器(如机器学习)对大约32000名客户进行分类。我调试了这个程序,发现对每个用户进行分类大约需要一秒钟的时间。换句话说,这需要8.8小时才能完成 有没有办法让我运行4个线程,每个线程处理8000个用户?第一个线程将处理1-8000、第二个8001-16000、第三个16001-23000、第四个23001-32000。另外,到目前为止,每个分类都是通过从另一个类调用静态

我没有多少制作多线程应用程序的经验,但我觉得我的程序正处于一个可以从多线程中获益的阶段。我正在做一个更大规模的项目,涉及使用分类器(如机器学习)对大约32000名客户进行分类。我调试了这个程序,发现对每个用户进行分类大约需要一秒钟的时间。换句话说,这需要8.8小时才能完成

有没有办法让我运行4个线程,每个线程处理8000个用户?第一个线程将处理1-8000、第二个8001-16000、第三个16001-23000、第四个23001-32000。另外,到目前为止,每个分类都是通过从另一个类调用静态函数来完成的

然后当主线程之外的其他线程结束时。这样做可行吗?如果是这样的话,如果有人能提供如何做到这一点的提示或步骤,我将不胜感激。我熟悉关键部分(等待/信号)的概念,但对它几乎没有经验


再次感谢您的帮助!欢迎提供有关如何处理此类情况的提示和建议!不确定这是否重要,但我有一台处理器速度为2.53 GHZ的Core 2 Duo PC。

这对于Apache Hadoop来说太轻了,它需要每个服务器大约64MB的数据块。。。但是这对Akka演员来说是一个绝佳的机会,而且,它恰好支持Java

基本上,您可以让4个参与者来完成这项工作,当他们完成对一个用户的分类时,或者更好地说,对多个用户进行分类时,他们要么将其传递给“接收者”参与者,将信息放入数据结构或文件中进行输出,要么,您可以通过让每个参与者自己写入一个文件来执行并发I/O。。然后,当文件全部完成时,可以检查/合并这些文件

如果你想变得更加花哨/强大,你可以把演员放在远程服务器上。与他们通信仍然非常容易,而且您可以利用多个服务器的CPU/资源


我自己写了一篇关于Akka演员的文章,但它是Scala的,所以我不给你们讲了。但是如果你在谷歌上搜索“阿克卡演员”,你会得到很多关于如何使用它的例子。勇敢一点,直接投入实验。“参与者系统”是一个很容易理解的概念。我知道你能做到

这对于Apache Hadoop来说太轻量级了,每台服务器需要大约64MB的数据块。。。但是这对Akka演员来说是一个绝佳的机会,而且,它恰好支持Java

基本上,您可以让4个参与者来完成这项工作,当他们完成对一个用户的分类时,或者更好地说,对多个用户进行分类时,他们要么将其传递给“接收者”参与者,将信息放入数据结构或文件中进行输出,要么,您可以通过让每个参与者自己写入一个文件来执行并发I/O。。然后,当文件全部完成时,可以检查/合并这些文件

如果你想变得更加花哨/强大,你可以把演员放在远程服务器上。与他们通信仍然非常容易,而且您可以利用多个服务器的CPU/资源


我自己写了一篇关于Akka演员的文章,但它是Scala的,所以我不给你们讲了。但是如果你在谷歌上搜索“阿克卡演员”,你会得到很多关于如何使用它的例子。勇敢一点,直接投入实验。“参与者系统”是一个很容易理解的概念。我知道你能做到

将数据拆分为实现Runnable的对象,然后将它们传递给新线程

在这种情况下,拥有四个以上的线程不会让你丧命,但是你不能得到比内核更多的并行工作(如注释中所述)——如果线程比内核多,那么系统将不得不处理谁在什么时候可以去

如果我有一个类客户,并且我想发布一个线程来对更多集合中的8000个客户进行优先级排序,我可能会这样做:

public class CustomerClassifier implements Runnable {

  private customer[] customers;

  public CustomerClassifier(customer[] customers) {
     this.customers = customers;
  }
  @Override
  public void run() {
    for (int i=0; i< customers.length; i++) {
      classify(customer);//critical that this classify function does not
                         //attempt to modify a resource outside this class
                         //unless it handles locking, or is talking to a database
                         //or something that won't throw fits about resource locking
    }
  }  
}
公共类CustomerClassifier实现可运行{
私人客户[]客户;
公共CustomerClassifier(客户[]客户){
这是。顾客=顾客;
}
@凌驾
公开募捐{
对于(int i=0;i
然后在别处发布这些线程

int jobSize = 8000;
customer[] customers = new customer[jobSize]();
int j = 0;
for (int i =0; i+j< fullCustomerArray.length; i++) {
  if (i == jobSize-1) {
    new Thread(new CustomerClassifier(customers)).start();//run will be invoked by thread
    customers = new Customer[jobSize]();
    j += i;
    i = 0;
  }
  customers[i] = fullCustomerArray[i+j];
}
int jobSize=8000;
客户[]客户=新客户[职位大小]();
int j=0;
对于(int i=0;i+j
如果你有你的分类方法影响到同一个资源的某个地方,你将不得不 实施锁定,也会在一定程度上扼杀您获得的优势

并发非常复杂,需要大量的思考,我还建议您查看oracle文档 (我知道链接不好,但希望oracle文档不会移动太多?)


免责声明:我不是并行设计或多线程(不同主题)方面的专家。

将数据拆分为实现可运行的对象,然后将它们传递给新线程

在这种情况下,拥有四个以上的线程不会让你丧命,但是你不能得到比内核更多的并行工作(如注释中所述)——如果线程比内核多,那么系统将不得不处理谁在什么时候可以去

如果我有一个类客户,并且我想发布一个线程来对更多集合中的8000个客户进行优先级排序,我可能会这样做:

public class CustomerClassifier implements Runnable {

  private customer[] customers;

  public CustomerClassifier(customer[] customers) {
     this.customers = customers;
  }
  @Override
  public void run() {
    for (int i=0; i< customers.length; i++) {
      classify(customer);//critical that this classify function does not
                         //attempt to modify a resource outside this class
                         //unless it handles locking, or is talking to a database
                         //or something that won't throw fits about resource locking
    }
  }  
}
公共类CustomerClassifier实现可运行{
私人客户