如何在此任务中仅运行一次任务

时间:2013-07-17 09:27:56

标签: java multithreading

我在WebApplication中有下面这段代码,无论何时用户登录到应用程序,基本上都会这样做。

  1. 将在用户登录操作期间调用addSymbols方法。
  2. 由于上述原因,PriorityBlockingQueue被启动
  3. PriorityBlockingQueue将符号添加到HashSet,然后迭代该HashSet以在新添加的符号上运行特定任务。
  4. 我面临的问题是,作为HashSet一部分的while循环一遍又一遍地执行相同的任务,因为它处于Thread的while条件中。

    我粘贴示例输出以了解与其相关的上下文。

    Symbol From priorityBlocking  SymbolTest
    Symbol From allSymbolsSet   SymbolTest
    Symbol From allSymbolsSet   SymbolTest
    Symbol From allSymbolsSet   SymbolTest
    Symbol From allSymbolsSet   SymbolTest
    Symbol From allSymbolsSet   SymbolTest
    Symbol From allSymbolsSet   SymbolTest
    Symbol From allSymbolsSet   SymbolTest
    Symbol From allSymbolsSet   SymbolTest
    Symbol From allSymbolsSet   SymbolTest
    Symbol From allSymbolsSet   SymbolTest
    

    这是我执行上述操作的代码。

    package com;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.PriorityBlockingQueue;
    
    public class TaskerThread extends Thread {
        private PriorityBlockingQueue<String> priorityBlocking = new PriorityBlockingQueue<String>();
        private Set<String> allSymbolsSet = new HashSet<String>();
         ExecutorService es = Executors.newFixedThreadPool(2);
    
        public void addSymbols(String str) {
            if (str != null) {
                priorityBlocking.add(str);
            }
        }
    
        public void run() {
            while (true) {
                try {
                    while (priorityBlocking.peek() != null) {
                        String symbol = priorityBlocking.poll();
                        allSymbolsSet.add(symbol);
                        try {
                            System.out.println("Symbol From priorityBlocking" +"  "+ symbol);
                        }   catch (Exception e) {
                                e.printStackTrace();
                        }
                    }
                    Iterator<String> ite = allSymbolsSet.iterator();
                    while (ite.hasNext()) {
                        String symbol = ite.next();
                        if (symbol != null && symbol.trim().length() > 0) {
                            try {
                                System.out.println("Symbol From allSymbolsSet"+"   "+symbol);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    Thread.sleep(2000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        public static void main(String args[]) {
            try {
                TaskerThread qT = new TaskerThread();
                qT.start();
                qT.addSymbols("SymbolTest");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    如果有任何方法可以让Iterator任务只运行一次,请告诉我。

1 个答案:

答案 0 :(得分:1)

我明白了。这是正在发生的事情:

您的循环开始,并且符号会添加到队列中。它在线程循环中从队列中拉出,然后迭代器循环运行。然后外循环(while (true))再次出现,这次,没有要添加的符号,但迭代器循环仍然执行。如果添加了新符号,则只需执行迭代器循环:

            boolean added = false;
            while (priorityBlocking.peek() != null) {
                added = true;
                String symbol = priorityBlocking.poll();
                allSymbolsSet.add(symbol);
                try {
                    System.out.println("Symbol From priorityBlocking" +"  "+ symbol);
                }   catch (Exception e) {
                        e.printStackTrace();
                }
            }
            if (added) {
                Iterator<String> ite = allSymbolsSet.iterator();
                while (ite.hasNext()) {
                    String symbol = ite.next();
                    if (symbol != null && symbol.trim().length() > 0) {
                        try {
                            System.out.println("Symbol From allSymbolsSet"+"   "+symbol);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

或者,在您没有任何要添加的内容时,使用takepoll(long,TimeUnit)也会停止循环。这也应该使循环的第二部分不必要地运行。您只需要处理InterruptedException