2

如何确保每个线程使用不同的唯一 ID,并且该 ID 应介于 startExistingRange 和 endExistingRange 之间。我很担心,因为该程序应该运行 60 分钟,而在 60 分钟之前,所有的 id 都可能已被使用,那么我该怎么办。我应该重置变量吗?什么是最佳实践?

例如:- 线程 1 将使用 25,线程 2 将使用 45 等等。

class ThreadTask implements Runnable {
    private int id;

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

    public void run() {
        System.out.println("Thread " + id);
    }
}

public class TestPool {

    public static void main(String[] args) {
        int size = 10;
        int durationOfRun = 60;
        int startExistingRange = 1;
        int endExistingRange = 1000;

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

        // queue some tasks
        long startTime = System.currentTimeMillis();
        long endTime = startTime + (durationOfRun*60*1000);

        // Running it for 60 minutes
        while(System.currentTimeMillis() <= endTime) {
/* I want each thread uses different unique ID between startExistingRange
 and endExistingRange */
            service.submit(new ThreadTask(What should I pass 
                 here so that each thread is using different ID));
        }

        // wait for termination        
        service.shutdown();
        service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); 
    }
}

更新:-

public class TestingPool {

    public static void main(String[] args) throws InterruptedException {
        int size = 10;
        int durationOfRun = 1;
        IdPool idPool = new IdPool();   
        // create thread pool with given size
        ExecutorService service = Executors.newFixedThreadPool(size); 

        // queue some tasks
        long startTime = System.currentTimeMillis();
        long endTime = startTime + (durationOfRun * 60 * 1000L);

        // Getting and releasing id in while loop
        while(System.currentTimeMillis() <= endTime) {
            Integer id = idPool.getId();
            service.submit(new ThreadTask(idPool, id));
            idPool.releaseId(id);
        }

        // wait for termination        
        service.shutdown();
        service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); 
    }

}

class IdPool {
    private final LinkedList<Integer> availableIds = new LinkedList<Integer>();

    public IdPool() {
        for (int i = 1; i <= 1000; i++) {
            availableIds.add(i);
        }
        Collections.shuffle(availableIds);
    }

    public synchronized Integer getId() {
        return availableIds.removeFirst();
    }

    public synchronized void releaseId(Integer id) {
        availableIds.add(id);
    }
}


class ThreadTask implements Runnable {
    private IdPool idPool;
    private int kk;

    public ThreadTask(IdPool idPool, int s) {
        this.idPool = idPool;
        this.kk = s;
    }

    public void run() {
        //Integer id = idPool.getId();
        System.out.println("Task " + kk);
        //idPool.releaseId(id);
    }
}
4

3 回答 3

2

不要在创建时将 ID 传递给您的任务,而是让您的任务从可用 ID 池中获取其 ID。由于您有 10 个线程,因此您只需要 10 个 ID。每个任务在启动时从池中获取一个 ID,并在完成时将其释放到池中。当然,池需要是线程安全的:

public class IdPool {
    private final LinkedList<Integer> availableIds = new LinkedList<Integer>();

    public IdPool() {
        for (int i = 1; i <= 1000; i++) {
            availableIds.add(i);
        }
    }

    public synchronized Integer getId() {
        return availabeIds.removeFirst();
    }

    public synchronized void releaseId(Integer id) {
        availableIds.add(id);
    }
}


class ThreadTask implements Runnable {
    private IdPool idPool;

    public ThreadTask(IdPool idPool) {
        this.idPool = idPool;
    }

    public void run() {
        Integer id = idPool.getId();
        System.out.println("Task " + id);
        idPool.releaseId(id);
    }
}

public class Main {
    public static void main(String[] args) throws InterruptedException {
        int size = 10;
        int durationOfRun = 60;
        IdPool idPool = new IdPool();   
        // create thread pool with given size
        ExecutorService service = Executors.newFixedThreadPool(size); 

        // queue some tasks
        long startTime = System.currentTimeMillis();
        long endTime = startTime + (durationOfRun * 60 * 1000L);

        // Running it for 60 minutes
        while(System.currentTimeMillis() <= endTime) {
            service.submit(new ThreadTask(idPool));
        }

        // wait for termination        
        service.shutdown();
        service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); 
    }
}
于 2012-05-25T18:38:32.460 回答
0

您可以跟踪集合中已经使用了哪些 ID(为方便起见,另一个用于未使用的 ID)。

然后你可以从 1 到 1000 开始 ID。当你用完时,你会在未使用的集合中查找可用的值

每次启动线程时,都会将该 id 从未使用的集合移动到已使用的集合,每次线程完成时,您都会执行相反的操作。

不可能用完 ID,因为您最多只能同时运行 10 个线程

于 2012-05-25T18:42:16.373 回答
0

您是否考虑过使用Thread.getID()

返回此线程的标识符。线程 ID 是创建此线程时生成的正长整数。线程 ID 是唯一的,并且在其生命周期内保持不变。当一个线程被终止时,这个线程 ID 可能会被重用

注意我的重点。

然后,您可以添加 100,000 *the number of seconds you have been running或其他内容。

添加- 应大众需求:

public void run() {
  Thread me = Thread.currentThread();
  // Name me from my ID.
  me.setName("X-" + me.getId());
  ...
于 2012-05-25T19:17:39.620 回答