Heim  >  Artikel  >  Java  >  Java-Implementierung des Multithread-ForkJoinPool-Falls

Java-Implementierung des Multithread-ForkJoinPool-Falls

黄舟
黄舟Original
2017-09-28 09:52:481502Durchsuche

Dieser Artikel stellt hauptsächlich die detaillierte Erklärung von Java-Multithread-ForkJoinPool-Beispielen und verwandten Inhalten im Zusammenhang mit dem ForkJoin-Framework vor. Freunde in Not können darauf verweisen.

Einführung

Java 7 bietet ein weiteres sehr nützliches Thread-Pool-Framework, das Fork/Join-Framework

Theorie

Das Fork/Join-Framework besteht hauptsächlich aus den folgenden zwei Klassen

* ForkJoinPool Diese Klasse implementiert die ExecutorService-Schnittstelle und den Work-Stealing-Algorithmus (Work - Diebstahlalgorithmus). Er verwaltet Arbeitsthreads und stellt Informationen zum Aufgabenstatus und zur Aufgabenausführung bereit.

* ForkJoinTask Diese Klasse ist eine Aufgabe, die in der ForkJoinPool-Basisklasse ausgeführt wird.

Das Fork/Join-Framework bietet einen Mechanismus zum Ausführen von fork()- und join()-Operationen in einer Aufgabe und eine Methode zur Steuerung des Aufgabenstatus. Um eine Fork/Join-Aufgabe zu implementieren, muss man normalerweise Folgendes tun: Sie müssen eine Unterklasse einer der folgenden beiden Klassen implementieren

* RecursiveAction wird in Szenarios verwendet, in denen die Aufgabe keinen Rückgabewert hat

* RecursiveTask wird in Szenarios verwendet wobei die Aufgabe einen Rückgabewert hat Jetzt haben wir uns das Ziel gesetzt, hundert Dollar zu verdienen. Zum Glück haben wir normale Untergebene, also können wir das eingrenzen Ziel und lassen Sie die jüngeren Brüder es verdienen. OK, fangen wir mit der Programmierung an.

Wenn das Ziel darin besteht, Geld zu verdienen Weniger als das Mindestziel, z. B. einhunderttausend, dann erledigen Sie es selbst. Andernfalls weisen Sie die Aufgabe den jüngeren Brüdern zu.


Endlich wir Schreiben Sie eine Testklasse


public class MakeMoneyTask extends RecursiveTask<Integer>{
  private static final int MIN_GOAL_MONEY = 100000;
  private int goalMoney;
  private String name;
  private static final AtomicLong employeeNo = new AtomicLong();
  public MakeMoneyTask(int goalMoney){
    this.goalMoney = goalMoney;
    this.name = "员工" + employeeNo.getAndIncrement() + "号";
  }
  @Override
  protected Integer compute() {
    if (this.goalMoney < MIN_GOAL_MONEY){
      System.out.println(name + ": 老板交代了,要赚 " + goalMoney + " 元,为了买车买房,加油吧....");
      return makeMoney();
    }else{
      int subThreadCount = ThreadLocalRandom.current().nextInt(10) + 2;
      System.out.println(name + ": 上级要我赚 " + goalMoney + ", 有点小多,没事让我" + subThreadCount + "个手下去完成吧," +
          "每人赚个 " + Math.ceil(goalMoney * 1.0 / subThreadCount) + "元应该没问题...");
      List<MakeMoneyTask> tasks = new ArrayList<>();
      for (int i = 0; i < subThreadCount; i ++){
        tasks.add(new MakeMoneyTask(goalMoney / subThreadCount));
      }
      Collection<MakeMoneyTask> makeMoneyTasks = invokeAll(tasks);
      int sum = 0;
      for (MakeMoneyTask moneyTask : makeMoneyTasks){
        try {
          sum += moneyTask.get();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
      System.out.println(name + ": 嗯,不错,效率还可以,终于赚到 " + sum + "元,赶紧邀功去....");
      return sum;
    }
  }
  private Integer makeMoney(){
    int sum = 0;
    int day = 1;
    try {
      while (true){
        Thread.sleep(ThreadLocalRandom.current().nextInt(500));
        int money = ThreadLocalRandom.current().nextInt(MIN_GOAL_MONEY / 3);
        System.out.println(name + ": 在第 " + (day ++) + " 天赚了" + money);
        sum += money;
        if (sum >= goalMoney){
          System.out.println(name + ": 终于赚到 " + sum + " 元, 可以交差了...");
          break;
        }
      }
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    return sum;
  }
}

Das Ergebnis nach der Operation ist wie folgt:


public class TestMain {
  public static void main(String[] args) throws ExecutionException, InterruptedException {
    ForkJoinPool pool = new ForkJoinPool();
    ForkJoinTask<Integer> task = pool.submit(new MakeMoneyTask(1000000));
    do {
      try {
        TimeUnit.MILLISECONDS.sleep(5);
      }catch (InterruptedException e){
        e.printStackTrace();
      }
    }while (!task.isDone());
    pool.shutdown();
    System.out.println(task.get());
  }
}


Haben Sie gesehen, dass Mitarbeiter Nr. 0 die Aufgabe von 1 Million direkt 10 Untergebenen zur Erledigung zugewiesen hat und jeder Untergebene sie weiter aufgeteilt hat, und schließlich wurde mit den Bemühungen von mehr als 70 Personen das Ziel von einer Million endlich erreicht? . Und es waren mehr als 800.000. Der Chef war so glücklich, dass er direkt mehr als 800.000 als Dividende an diese mehr als 70 Mitarbeiter ausgeschüttet hat >

Durch das Studium des obigen Beispiels glaube ich, dass viele Leute die ForkJoinPool-Klasse beherrschen können. Wenn die Zielaufgabe zu groß ist, dann warten Sie, bis diese Unteraufgaben erledigt sind abgeschlossen sein. Schließen Sie abschließend die zuvor festgelegte Zielaufgabe ab

Das obige ist der detaillierte Inhalt vonJava-Implementierung des Multithread-ForkJoinPool-Falls. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn