2

私は、各スレッドがID特定の範囲で毎回一意になるようにする必要があるプロジェクトに取り組んでいます。例えば-

If number of threads is 2and number of tasks is 10then 各スレッドは 10 個のタスクを実行します。つまり、2 つのスレッドが 20 のタスクを実行することになります。

だから私はこのようなものを探しています -

上記の例では、最初のスレッドは を使用しid between 1 and 10、2 番目のスレッドは を使用する必要がありますid between 11 and 20

もう一つの例。したがって、もし私が持ってい3 threadnumber of tasks as 20、最初のスレッドが ID を使用し1 and 20、2 番目のスレッドが間に21 and 40あり、3 番目のスレッドが間にあるとし41 and 60ます。

以下は私がこれまでに持っているコードです。それが行うことは、IDを取得しAtomicInteger、1から始まるたびに一意のIDを取得することです.

class ThreadTask implements Runnable {
    private final AtomicInteger id;
    private int noOfTasks;

    public ThreadTask(AtomicInteger id2, int noOfTasks) {
        this.id = id2;
        this.noOfTasks = noOfTasks;
    }

    @Override
    public void run() {

        while(noOfTasks > 0) {
            System.out.println(id.getAndIncrement());
              // And use this id for other things.
        noOfTasks--;
         }
    }
}

public class XMPTest {

    public static void main(String[] args) {

        final int noOfThreads = 2;
        final int noOfTasks = 10;

        final AtomicInteger id = new AtomicInteger(1);

        //create thread pool with given size 
        ExecutorService service = Executors.newFixedThreadPool(noOfThreads);

        // queue some tasks 
        for (int i = 0; i < noOfThreads; i++) {
            service.submit(new ThreadTask(id, noOfTasks));
        }
    }
}

1 and 10スレッド1がIDを取得し、2番目のスレッドがIDを取得するように制限するにはどうすればよいですか11 and 20

更新されたコード:- 以下のコードを試しています

public static void main(String[] args) {

    final int noOfThreads = 2;
    final int noOfTasks = 10;

    //create thread pool with given size 
    ExecutorService service = Executors.newFixedThreadPool(noOfThreads);

    // queue some tasks 
    for (int i = 0, int nextId = 1; i < noOfThreads; i++, nextId += noOfTasks) {
        service.submit(new ThreadTask(nextId, noOfTasks));
    }
}


class ThreadTask implements Runnable {
    private final int id;
    private int noOfTasks;

    public ThreadTask(int nextId, int noOfTasks) {
        this.id = nextId;
        this.noOfTasks = noOfTasks;
    }

    public void run() {

        for (int i = id; i <= noOfTasks; i++) {
            System.out.println(i);
        }
    }
}

したがって、最初のスレッドでは 1 ~ 10 が出力されますが、これで問題ありません。しかし、2 番目のスレッドでは、nextId は 11 で、noOfTasks は 10 であるため、for ループは run メソッドで 2 回目に動作します。

4

2 に答える 2

1

スレッドを起動する前に、シングルスレッド コードで必要に応じて範囲を分割し、その範囲を各スレッドに渡します。

例えば:

public static void main(String[] args) {

    final int noOfThreads = 2;
    final int noOfTasks = 10;

    //create thread pool with given size 
    ExecutorService service = Executors.newFixedThreadPool(noOfThreads);

    // queue some tasks 
    for (int i = 0, int nextId = 1; i < noOfThreads; i++, nextId += noOfTasks) {
        service.submit(new ThreadTask(nextId, noOfTasks));
    }
}

class ThreadTask implements Runnable {
    private final int id;
    private int noOfTasks;

    public ThreadTask(int nextId, int noOfTasks) {
        this.id = nextId;
        this.noOfTasks = noOfTasks;
    }

    public void run() {

        for (int i = id; i < id + noOfTasks; i++) {
            System.out.println(i);
        }
    }
}
于 2013-02-12T03:06:02.390 に答える
0

id をインクリメントする必要があるため、最終的なものにすることはできません。Dispatcher スレッド (この場合はメイン関数を処理するスレッド) に競合がないため、AtomicInteger を使用する必要がある理由もわかりません。それでも使用する必要がある場合は、これが私が行う方法です。

public class XMPTest {

public static void main(String[] args) {

    final int noOfThreads = 2;
    final int noOfTasks = 10;

    AtomicInteger id = new AtomicInteger(1);

    //create thread pool with given size 
    ExecutorService service = Executors.newFixedThreadPool(noOfThreads);

    // queue some tasks 
    for (int i = 0; i < noOfThreads; i++) {
        service.submit(new ThreadTask(id, noOfTasks));
        id.addAndGet(1);
    }
}

}

于 2013-02-12T03:03:30.040 に答える