0

所以我有一个小问题。我在一个循环中检查很多数字,其中数字只是一个AtomicInteger每次递增的数字。问题是有时会出现“错误”(错误与服务器有关,而不是程序)并且线程需要休眠。在他们睡觉后,我希望所有线程返回并重新检查由于错误而错过的数字,但它只会重新检查最后一个,因为AtomicInteger已经增加了。这是我的代码:

public class Red extends java.lang.Thread {
        private final LinkedBlockingQueue<Integer> queue;

    public Red(LinkedBlockingQueue<Integer> queue) {
        this.queue = queue;
    }

        public void run()
    {
while(true){
    try{
int i = queue.take();
Main.code.setValueAttribute(""+i);
HtmlPage reply = (HtmlPage)Main.btnFinal.click();
Main.webClient.waitForBackgroundJavaScript(Main.r.nextInt(500));
if ( reply.asText().indexOf( "Error" ) > -1 || reply.asText().indexOf( "unavailable" ) > -1) {
int sleep = Main.r.nextInt(900000);
System.out.println(" error, on "+i+" sleeping for "+ sleep);
Thread.sleep(sleep);
continue;
}
System.out.println("Code "+i+" checked.");
    }catch(Exception e){
        e.printStackTrace();
        continue;
    }
}

        }
}

这是我为线程加注星标的代码:

List<LinkedBlockingQueue<Integer>> queuelist = new ArrayList<LinkedBlockingQueue<Integer>>();
   for (int n = 0; n < threads; n++) {
    queuelist.add(new LinkedBlockingQueue<Integer>());
    java.lang.Thread t = new Red(queuelist.get(n));
    t.start();
   }
java.lang.Thread a = new MainThread(queuelist);
a.start();

这是我的 MainThread 代码:

public class MainThread extends java.lang.Thread {
    final private List<LinkedBlockingQueue<Integer>> queues;
    final private AtomicInteger atomicInteger = new AtomicInteger(10000000);

    public MainThread(List<LinkedBlockingQueue<Integer>> queues) {
        this.queues = queues;
    }

    public void run() {
        while (true) {
            int temp = atomicInteger.getAndIncrement();
            for(LinkedBlockingQueue<Integer> queue : queues) {
                queue.offer(temp);
            }
        }
    }
}
4

1 回答 1

0

如果我理解这个问题,那么一种解决方案是给每个线程自己的BlockingQueue<Integer>or ConcurrentLinkedQueue<Integer>; 然后主线程的循环将增加每个队列的值AtomicIntegeroffer它的值,线程将takepoll在它们的队列上检索整数并处理它们。这样,如果一个线程休眠,它就不会错过任何整数——当它醒来时,它们会在队列中等待它。

public class MainThread extends java.lang.Thread {
    final private List<BlockingQueue<Integer>> queues;
    final private AtomicInteger atomicInteger = new AtomicInteger();

    public MainThread(List<BlockingQueue<Integer>> queues) {
        this.queues = queues;
    }

    public void run() {
        while (true) {
            int temp = atomicInteger.getAndIncrement();
            for(BlockingQueue<Integer> queue : queues) {
                queue.offer(temp);
            }
        }
    }
}

public class WorkerThread extends java.lang.Thread {
    private final BlockingQueue<Integer> queue;

    public WorkerThread(BlockingQueue<Integer> queue) {
        this.queue = queue;
    }

    public void run() {
        while(true) {
            int temp = queue.take();
            // process temp
        }
    }
}
于 2013-06-03T01:26:01.533 回答