2

我正在做一个项目,我需要确保每个线程ID在特定范围内每次都是唯一的。例如-

如果number of threads is 2然后number of tasks is 10每个线程将执行 10 个任务。这意味着 2 个线程将执行 20 个任务。

所以我正在寻找这样的东西 -

在上面的例子中,第一个线程应该使用id between 1 and 10,第二个线程应该使用id between 11 and 20

另一个例子。所以假设如果我有3 threadnumber of tasks as 20那么第一个线程应该使用 ID between 1 and 20,第二个线程应该在 between21 and 40和第三个线程之间41 and 60

下面是我到目前为止的代码,它的作用是将 id 作为 anAtomicInteger并且每次从 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 应该在之间获得 id,1 and 10而第二个线程应该在之间获得 id11 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 这很好。但是在第二个线程中,nextId 是 11,noOfTasks 是 10,所以我的 for 循环将第二次在 run 方法中工作。

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,因此它不能是最终的。我也不明白为什么需要使用 AtomicInteger,因为 Dispatcher 线程(在这种情况下处理 main 函数的线程)中没有争用。如果您仍然需要使用它,我会这样做。

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 回答