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 個のスレッドがあるため、必要な ID は 10 個だけです。各タスクは、起動時にプールから 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

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 に答える
0

セットで既に使用されている ID を追跡できます (また、便宜上、使用されていない ID の別の ID も追跡できます)。

次に、1 から 1000 までの ID を開始できます。不足したら、未使用のセットで使用可能な値を探します。

スレッドを開始するたびに、その id を未使用のセットから使用済みのセットに移動し、スレッドが終了するたびに、その逆を行います。

同時に実行できるスレッドは最大 10 であるため、ID が不足することはありません。

于 2012-05-25T18:42:16.373 に答える