运行程序60分钟,每个线程使用不同的ID

时间:2012-05-25 18:32:39

标签: java multithreading threadpool executorservice

如何确保每个线程使用不同的唯一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);
    }
}

3 个答案:

答案 0 :(得分: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); 
    }
}

答案 1 :(得分:0)

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

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

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

由于您最多只能同时运行10个线程,因此无法用完ID

答案 2 :(得分:0)

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

  

返回此Thread的标识符。线程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());
  ...