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

Java 如何在此任务中仅运行一次任务,java,multithreading,Java,Multithreading,我的WebApplication中有下面这段代码,只要用户登录到应用程序,它基本上就是这样做的 用户登录操作期间将调用addSymbols方法 由于上述原因,PriorityBlockingQueue被激活 PriorityBlockingQueue将符号添加到哈希集,然后对哈希集进行迭代以在新添加的符号上运行特定任务 我在这里面临的问题是,作为HashSet一部分的while循环在线程的while-true条件下一遍又一遍地执行相同的任务 我粘贴示例输出是为了理解与之相关的上下文 Symbol

我的WebApplication中有下面这段代码,只要用户登录到应用程序,它基本上就是这样做的

  • 用户登录操作期间将调用addSymbols方法
  • 由于上述原因,PriorityBlockingQueue被激活
  • PriorityBlockingQueue将符号添加到哈希集,然后对哈希集进行迭代以在新添加的符号上运行特定任务
  • 我在这里面临的问题是,作为HashSet一部分的while循环在线程的while-true条件下一遍又一遍地执行相同的任务

    我粘贴示例输出是为了理解与之相关的上下文

    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();
            }
        }
    }
    
    package-com;
    导入java.util.HashSet;
    导入java.util.Iterator;
    导入java.util.Set;
    导入java.util.concurrent.ExecutorService;
    导入java.util.concurrent.Executors;
    导入java.util.concurrent.PriorityBlockingQueue;
    公共类TaskerThread扩展线程{
    private PriorityBlockingQueue priorityBlocking=new PriorityBlockingQueue();
    private Set allSymbolsSet=new HashSet();
    Executors服务es=Executors.newFixedThreadPool(2);
    公共void addSymbols(字符串str){
    如果(str!=null){
    优先阻塞。添加(str);
    }
    }
    公开募捐{
    while(true){
    试一试{
    while(priorityBlocking.peek()!=null){
    String symbol=priorityBlocking.poll();
    所有符号集。添加(符号);
    试一试{
    System.out.println(“来自优先级阻塞的符号”+“”+Symbol);
    }捕获(例外e){
    e、 printStackTrace();
    }
    }
    迭代器ite=allsymbolset.Iterator();
    while(ite.hasNext()){
    字符串符号=ite.next();
    如果(symbol!=null&&symbol.trim().length()>0){
    试一试{
    System.out.println(“来自所有符号集的符号”+“”+Symbol);
    }捕获(例外e){
    e、 printStackTrace();
    }
    }
    }
    《睡眠》(2000年);
    }捕获(例外e){
    e、 printStackTrace();
    }
    }
    }
    公共静态void main(字符串参数[]){
    试一试{
    TaskerThread qT=new TaskerThread();
    qT.start();
    qT.添加符号(“SymbolTest”);
    }捕获(例外e){
    e、 printStackTrace();
    }
    }
    }
    

    请告诉我是否有任何方法可以使迭代器任务只运行一次。

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

    循环开始,一个符号被添加到队列中。它从线程循环中的队列中退出,然后迭代器循环运行。然后外部循环(
    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();
                            }
                        }
                    }
                }
    
    boolean added=false;
    while(priorityBlocking.peek()!=null){
    添加=真;
    String symbol=priorityBlocking.poll();
    所有符号集。添加(符号);
    试一试{
    System.out.println(“来自优先级阻塞的符号”+“”+Symbol);
    }捕获(例外e){
    e、 printStackTrace();
    }
    }
    如有(新增){
    迭代器ite=allsymbolset.Iterator();
    while(ite.hasNext()){
    字符串符号=ite.next();
    如果(symbol!=null&&symbol.trim().length()>0){
    试一试{
    System.out.println(“来自所有符号集的符号”+“”+Symbol);
    }捕获(例外e){
    e、 printStackTrace();
    }
    }
    }
    }
    

    或者,在您没有任何要添加的内容时,使用or也会停止循环。这还可以防止循环的第二部分不必要地运行。您只需要处理
    InterruptedException

    我不能将迭代部分代码保持在while true条件之外,因为如果我这样做,如果有新用户登录,我将错过要执行的任务。不确定它是否解决了任何问题,但您可能希望使用,或者因为它们会阻塞。这将阻止循环在队列中没有任何内容时运行。您还应该能够删除手册
    sleep
    then。您可以在allsymbolset中添加符号,但从不删除它们。因此,在你的while(true)中,你将始终打印所有symbols@fluminis从AllSymbolset中删除符号将有何帮助??因为每个用户都有一个唯一的符号。我使用了您的代码并运行了它,但我仍然看到迭代器不断地执行。这是预期的,因为一旦该标志设置为true,它将继续运行。如果我遗漏了任何内容,请告诉我。该标志是
    try
    块的本地标志。每次循环循环时,它都应该得到一个新值。如果只添加一次,那么它应该只执行一次。如果您添加多个项目,每次添加内容时都会执行。谢谢,这很有意义,现在就尝试,看起来不错,这很好,但是您能否告诉我,如果使用take from priorityBlockingQueue而不是您粘贴的上述代码,我会得到什么好处。目前,外部
    白色(true)
    循环每2秒运行一次,无论是否有任何事情要做。当不添加任何内容时,整个迭代本质上是对CPU周期的浪费。使用