java - 将任务划分为线程 - 多线程

标签 java multithreading output threadpool

我想从给定的大量数字中生成对。我正在使用两个 for 循环和线程。我在代码中的函数 getAllPairs() 生成具有给定数字数组的一对。

我有一个长度为1000的数组。使用一个线程,输出时间接近15秒。现在我想使用5-6个线程并减少这个输出时间。我坚持把这个任务平均分配给五个线程。如果不是线程,如何减少输出时间?

由于我花了很多时间学习多线程,因此线程解决方案受到赞赏。我想实现它。

import java.util.*;


 class Pair {
 public int x, y;
 public Pair(int x, int y) {
  this.x = x;
  this.y = y;
 }
  @Override
    public String toString(){
        return " ( " + x + " ," + y + " ) " ;
    }
}


class selectPairs{
 private int[] array;
 private List<Pair> totalPairs ;

 public selectPairs(int[] arr){
     array = arr;
 }
 //set Method
 public void settotalPairs(List<Pair> pieces){
     totalPairs = pieces;
 }
 //get Method
 public List<Pair> gettotalPairs(){
     return totalPairs;
 }

 // Method to generate pairs
 public List<Pair> getAllPairs() {
  List<Pair> pairs = new ArrayList<Pair>();
  int total = array.length;
  for(int i=0; i < total; i++) {
  int num1 = array[i];
  for(int j=i+1; j < total; j++) {
   int num2 = array[j];
   pairs.add(new Pair(num1,num2));
   }
  }
  return pairs;
 } 
}


// Thread class
class ThreadPairs extends Thread {
   private Thread t;
   selectPairs SP;

   ThreadPairs(selectPairs sp){

        SP = sp;
   }
   public void run() {
      synchronized(SP) {
       List<Pair> PAIRS = SP.getAllPairs();
       SP.settotalPairs(PAIRS);
     }
   }
}

 public class TestThread {
   public static void main(String args[]) {

       int[] a = new int[1000]; 
       for (int i = 0; i < a.length; i++) { 
        a[i] = i ;
        }

      selectPairs ob = new selectPairs(a);
      ThreadPairs T = new ThreadPairs(  ob );
      T.start();

      while (true) {
        try {
         T.join(); 
         break;
        }
        catch(Exception e){
        }
      }

      List<Pair> Total = new ArrayList<Pair>() ;
      List<Pair> Temp1 = ob.gettotalPairs();
      Total.addAll(Temp1);
      System.out.println(Total);
   }
}

最佳答案

具有线程池、任务分割策略并收集所有结果的解决方案:

public class SelectPairs {

    private static final int NUM_THREADS = 8;

    private int[] array;

    public SelectPairs(int[] arr) {
        array = arr;
    }

    // A splitting task strategy
    public List<Pair> getPartialPairs(int threadIndex, int numThreads) {
        List<Pair> pairs = new ArrayList<Pair>();
        int total = array.length;
        for (int i = threadIndex; i < total; i += numThreads) {
            int num1 = array[i];
            for (int j = i + 1; j < total; j++) {
                int num2 = array[j];
                pairs.add(new Pair(num1, num2));
            }
        }
        return pairs;
    }

    // To use Callables or Runnables are better than extends a Thread.
    public static class PartialPairsCall implements Callable<List<Pair>> {

        private int thread;
        private int totalThreads;
        private SelectPairs selectPairs;

        public PartialPairsCall(int thread, int totalThreads, SelectPairs selectPairs) {
            this.thread = thread;
            this.totalThreads = totalThreads;
            this.selectPairs = selectPairs;
        }

        @Override
        public List<Pair> call() throws Exception {
            return selectPairs.getPartialPairs(thread, totalThreads);
        }
    }


    public static void main(String[] args) throws Exception {

        int[] a = new int[1000];
        for (int i = 0; i < a.length; i++) {
            a[i] = i;
        }
        SelectPairs sp = new SelectPairs(a);

        // Create a thread pool 
        ExecutorService es = Executors.newFixedThreadPool(NUM_THREADS);
        List<Future<List<Pair>>> futures = new ArrayList<>(NUM_THREADS);

        // Submit task to every thread:
        for (int i = 0; i < NUM_THREADS; i++) {
            futures.add(es.submit(new PartialPairsCall(i, NUM_THREADS, sp)));
        }

        // Collect the results:
        List<Pair> result = new ArrayList<>(a.length * (a.length - 1));
        for (Future<List<Pair>> future : futures) {
            result.addAll(future.get());
        }

        // Shutdown thread pool
        es.shutdown();

        System.out.println("result: " + result.size());
    }
}

关于java - 将任务划分为线程 - 多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31509949/

相关文章:

java - 可能因不同原因而失败的方法的标准模式是什么?

java - 组织.apache.catalina.LifecycleException : Failed to start component

Java - Java 线程可以多次调用启动吗?

c - 是否有安全的方法来检查 pthread 是否存在?

c++ - 输出未按正确顺序打印

java - 在 GUI 中使用预定义的字符串

Java 读取和写入标准流不工作

Java mysql 查询 ("SELECT * FROM movies"仅返回 1 行

java - 从 JApplet 内的 Jpanel 在新选项卡中打开 url

java - 如何在java中将进程构建器命令作为线程运行