2012-12-28 29 views
2

我想改進我的fork/join小示例,以顯示在Java Fork/Join框架執行期間發生偷工作。如何顯示在Java Fork/Join框架中發生偷工作?

我需要對代碼進行哪些更改?示例的目的:僅對線程進行線性研究,以瞭解在多個線程之間分解工作的值。

package com.stackoverflow.questions; 

import java.util.LinkedList; 
import java.util.List; 
import java.util.Random; 
import java.util.concurrent.ForkJoinPool; 
import java.util.concurrent.RecursiveTask; 

public class CounterFJ<T extends Comparable<T>> extends RecursiveTask<Integer> { 

    private static final long serialVersionUID = 5075739389907066763L; 
    private List<T> _list; 
    private T _test; 
    private int _lastCount = -1; 
    private int _start; 
    private int _end; 
    private int _divideFactor = 4; 

    private static final int THRESHOLD = 20; 

    public CounterFJ(List<T> list, T test, int start, int end, int factor) { 
     _list = list; 
     _test = test; 
     _start = start; 
     _end = end; 
     _divideFactor = factor; 

    } 

    public CounterFJ(List<T> list, T test, int factor) { 
     this(list, test, 0, list.size(), factor); 
    } 

    @Override 
    protected Integer compute() { 

     if (_end - _start < THRESHOLD) { 
      int count = 0; 
      for (int i = _start; i < _end; i++) { 
       if (_list.get(i).compareTo(_test) == 0) { 
        count++; 
       } 
      } 
      _lastCount = count; 
      return new Integer(count); 
     } 
     LinkedList<CounterFJ<T>> taskList = new LinkedList<>(); 

     int step = (_end - _start)/_divideFactor; 
     for (int j = 0; j < _divideFactor; j++) { 
      CounterFJ<T> task = null; 
      if (j == 0) 
       task = new CounterFJ<T>(_list, _test, _start, _start + step, _divideFactor); 
      else if (j == _divideFactor - 1) 
       task = new CounterFJ<T>(_list, _test, _start + (step * j), _end, _divideFactor); 
      else 
       task = new CounterFJ<T>(_list, _test, _start + (step * j), _start + (step * (j + 1)), _divideFactor); 

      // task.fork(); 
      taskList.add(task); 
     } 
     invokeAll(taskList); 

     _lastCount = 0; 
     for (CounterFJ<T> task : taskList) { 
      _lastCount += task.join(); 
     } 

     return new Integer(_lastCount); 

    } 

    public int getResult() { 
     return _lastCount; 
    } 

    public static void main(String[] args) { 

     LinkedList<Long> list = new LinkedList<Long>(); 
     long range = 200; 
     Random r = new Random(42); 

     for (int i = 0; i < 1000; i++) { 
      list.add(new Long((long) (r.nextDouble() * range))); 
     } 

     CounterFJ<Long> counter = new CounterFJ<>(list, new Long(100), 4); 

     ForkJoinPool pool = new ForkJoinPool(); 
     long time = System.currentTimeMillis(); 
     pool.invoke(counter); 

     System.out.println("Fork join counter in " + (System.currentTimeMillis() - time)); 
     System.out.println("Occurrences:" + counter.getResult()); 

    } 

} 
+2

+1你的努力爲您解決自己的問題。 – Trying

+0

非常感謝,@Trying – giampaolo

回答

6

最後,我管理如何和它並不難,所以我留給未來的讀者。

RecursiveTask的costructor保存線程創建實例本身。在compute方法中檢查執行線程是否相同。如果沒有發生盜竊工作。

所以我加入這個成員變量

private long _threadId = -1; 
private static int stolen_tasks = 0; 

改變的構造是這樣的:

​​

,並加入到比較方法compute

@Override 
    protected Integer compute() { 

     long thisThreadId = Thread.currentThread().getId(); 
     if (_threadId != thisThreadId){ 
      stolen_tasks++; 
     } 
    // rest of the method