java线程池保持运行

发布于 2024-09-08 10:55:37 字数 221 浏览 8 评论 0原文

这更像是一个一般性问题,而不是一个具体问题。我试图拥有一个保持活动状态的多线程环境,以便我可以提交任务并运行它们。我希望能够避免在 Web 服务器或应用程序服务器中执行的麻烦。我们的想法是为此使用 java 线程池,但这里的问题是池一直保持打开状态,直到我的 main 方法完成,之后显然它会关闭并且程序完成。我怎样才能防止这种情况发生?我确信有几种选择,其中一些比其他更天真(虽然我想到了真正的循环)。 有什么想法吗?谢谢。

This is more a generic question than a specific one. I'm trying to have a multi threaded environment that stays active so that I can just submit tasks and run them. I want to do this without the hassle of executing in a web server or application server. The idea was to use a java thread pool for this, but the issue here is that the pool stays open just until my main method finishes, after which obviously it closes and the program finishes. How can I prevent this from happening? I'm sure there are several options, some more naive than others (while true loops come to mind).
Any ideas? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

请爱~陌生人 2024-09-15 10:55:37

您的任务如何被接受?

在许多情况下,我看到有 1 个线程正在等待或轮询任务并将其传递。该线程将使您的应用程序保持活动状态,还可以等待某些标志来关闭应用程序,并等待当前作业完成并清理。

总而言之,我发现处理这些应用程序生命周期事件的麻烦程度超过了部署到像 Jetty 这样的简单容器的麻烦程度。特别是对于在后台运行的东西,我在几个愚蠢的 JSP 页面中发现了很多价值,可以验证它是否仍在工作(与我们的自动监控集成)并获取一些统计数据。

How are your tasks being accepted?

In many cases I saw there was 1 thread waiting or polling from tasks and passing them on. This thread will keep your application alive and can also wait for some sign to shutdown the application and the wait for the current jobs to be finished and clean up.

All in all I find that the point where the hassle of dealing with these application lifecycle events exceed the hassle of deploying to a simple container like Jetty is easily reached. Especially for things running in the background I find a lot of value in a couple of silly JSP pages to verify it is still working (to integrate with our automatic monitoring) and getting some statistics.

漆黑的白昼 2024-09-15 10:55:37

这是我在某些程序中的 main() 末尾调用的一些代码。如果用户在命令行上键入“quit”,则程序将进行清理,然后退出。或者,您可以修改用户输入“操作”以执行其他操作的位置。

   public void serve() throws IOException
   {
      BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
      PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
      String line = null;

      for (;;)
      {
         out.print("> ");
         out.flush();
         line = in.readLine();
         if (line == null)
         {
            break;                  // QUIT if we get EOF
         }

         try
         {
            // Use a stringTokenizer to parse the user's command
            StringTokenizer t = new StringTokenizer(line);

            // blank line
            if (!t.hasMoreTokens())
            {
               continue;
            }

            // get the first word of the input and convert to lower case
            String command = t.nextToken().toLowerCase();

            if (command.equals("quit"))
            {
               bTerminate = true;
               // Do all cleanup here
               myClient.close();
               break;
            }
            else if (command.equals("action"))
            {
               if (line.length() > command.length())
               {
                  // get data from rest of line
                  String data = line.substring(command.length()).trim();
                  // perform action
                  myOutputStream.writeUTF(data);
               }
            }
         }
         catch(Exception e)
         {
            e.printStackTrace();
         }
      }
      out.close();
      in.close();
   }

Here is some code that I call at the end of my main() in some programs. If the user types "quit" on the command line then the program cleans up and then exits. Or else you can modify where if the user enters "action" to do something else.

   public void serve() throws IOException
   {
      BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
      PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
      String line = null;

      for (;;)
      {
         out.print("> ");
         out.flush();
         line = in.readLine();
         if (line == null)
         {
            break;                  // QUIT if we get EOF
         }

         try
         {
            // Use a stringTokenizer to parse the user's command
            StringTokenizer t = new StringTokenizer(line);

            // blank line
            if (!t.hasMoreTokens())
            {
               continue;
            }

            // get the first word of the input and convert to lower case
            String command = t.nextToken().toLowerCase();

            if (command.equals("quit"))
            {
               bTerminate = true;
               // Do all cleanup here
               myClient.close();
               break;
            }
            else if (command.equals("action"))
            {
               if (line.length() > command.length())
               {
                  // get data from rest of line
                  String data = line.substring(command.length()).trim();
                  // perform action
                  myOutputStream.writeUTF(data);
               }
            }
         }
         catch(Exception e)
         {
            e.printStackTrace();
         }
      }
      out.close();
      in.close();
   }
娇纵 2024-09-15 10:55:37

这是我为另一篇文章编写的示例,它允许您在可以向其发布消息的另一个线程上提供线程池。 main() 创建线程,还允许您在需要时停止线程。要阻止 main 完成,只需消除processor.stopProcessing();主线。

package com.rch.test;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

public class Executor
{
    /**
     * Class to encapsulate a request
     * 
     * @author romain
     */
    static class Request
    {
        String someText;

        Request(String someText)
        {
            this.someText = someText;
        }

        public String getSomeText()
        {
            return someText;
        }
    }

    /**
     * Creates a Thread that listens on a queue to process messages
     * 
     * @author romain
     */
    static class ServerThread implements Runnable
    {
        private BlockingQueue<Request> queue = new LinkedBlockingQueue<Request>();
        volatile boolean stop = false;

        /**
         * Does all the work
         */
        @Override
        public void run()
        {
            ExecutorService pool = Executors.newFixedThreadPool(3);
            try
            {
                while (!stop)
                {
                    Request req = queue.poll(1000L, TimeUnit.MILLISECONDS);
                    if (req != null)
                    {
                        Runnable runnable = new Executor.ImageProcessor(req);
                        pool.execute(runnable);
                    }
                }
            }
            catch (InterruptedException ie)
            {
                System.out.println("Log something here");
            }
            finally
            {
                pool.shutdown();
            }
        }

        /**
         * Accepts a message on the queue
         * @param request
         */
        public void accept(Request request)
        {
            queue.add(request);
        }

        public void stopProcessing()
        {
            stop = true;
        }
    }

    /**
     * class to do the actual work
     * @author romain
     */
    static class ImageProcessor implements Runnable
    {
        String someText;

        ImageProcessor(Request req)
        {
            this.someText = req.getSomeText();
        }

        @Override
        public void run()
        {
            System.out.println(someText);
            // Process Image here
        }
    }

    /**
     * Test Harness
     * @param args
     */
    public static void main(String[] args)
    {
        // Initialize 
        ServerThread processor = new ServerThread();
        Thread aThread = new Thread(processor);
        aThread.start();

        // Wait for Thread to start
        try
        {
            Thread.sleep(500L);
        }
        catch (InterruptedException e1)
        {
            e1.printStackTrace();
        }

        for (int i = 0; i < 100; i++)
        {
            String text = "" + i;
            Request aRequest = new Request(text);
            processor.accept(aRequest);
        }

        // Give it enough time to finish
        try
        {
            Thread.sleep(500L);
        }
        catch (InterruptedException e1)
        {
            e1.printStackTrace();
        }

        // Tell the thread to finish processing
        processor.stopProcessing();

        // Wait for the Thread to complete
        try
        {
            aThread.join();
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}

Here is a sample I wrote for another post that allows you to gave a Thread Pool on another Thread that you can post messages to. The main() creates the Threads and also allows you to stop the Thread when you want. To stop main from finishing just eliminate the processor.stopProcessing(); line in main.

package com.rch.test;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

public class Executor
{
    /**
     * Class to encapsulate a request
     * 
     * @author romain
     */
    static class Request
    {
        String someText;

        Request(String someText)
        {
            this.someText = someText;
        }

        public String getSomeText()
        {
            return someText;
        }
    }

    /**
     * Creates a Thread that listens on a queue to process messages
     * 
     * @author romain
     */
    static class ServerThread implements Runnable
    {
        private BlockingQueue<Request> queue = new LinkedBlockingQueue<Request>();
        volatile boolean stop = false;

        /**
         * Does all the work
         */
        @Override
        public void run()
        {
            ExecutorService pool = Executors.newFixedThreadPool(3);
            try
            {
                while (!stop)
                {
                    Request req = queue.poll(1000L, TimeUnit.MILLISECONDS);
                    if (req != null)
                    {
                        Runnable runnable = new Executor.ImageProcessor(req);
                        pool.execute(runnable);
                    }
                }
            }
            catch (InterruptedException ie)
            {
                System.out.println("Log something here");
            }
            finally
            {
                pool.shutdown();
            }
        }

        /**
         * Accepts a message on the queue
         * @param request
         */
        public void accept(Request request)
        {
            queue.add(request);
        }

        public void stopProcessing()
        {
            stop = true;
        }
    }

    /**
     * class to do the actual work
     * @author romain
     */
    static class ImageProcessor implements Runnable
    {
        String someText;

        ImageProcessor(Request req)
        {
            this.someText = req.getSomeText();
        }

        @Override
        public void run()
        {
            System.out.println(someText);
            // Process Image here
        }
    }

    /**
     * Test Harness
     * @param args
     */
    public static void main(String[] args)
    {
        // Initialize 
        ServerThread processor = new ServerThread();
        Thread aThread = new Thread(processor);
        aThread.start();

        // Wait for Thread to start
        try
        {
            Thread.sleep(500L);
        }
        catch (InterruptedException e1)
        {
            e1.printStackTrace();
        }

        for (int i = 0; i < 100; i++)
        {
            String text = "" + i;
            Request aRequest = new Request(text);
            processor.accept(aRequest);
        }

        // Give it enough time to finish
        try
        {
            Thread.sleep(500L);
        }
        catch (InterruptedException e1)
        {
            e1.printStackTrace();
        }

        // Tell the thread to finish processing
        processor.stopProcessing();

        // Wait for the Thread to complete
        try
        {
            aThread.join();
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}
失而复得 2024-09-15 10:55:37

你绝对可以做的是一个像这样的循环:

while (true) {
  Thread.sleep(1000);
}

如果你不想停止这个进程,你就杀死它。然而,这并不是一个优雅的解决方案。

更好的是,监听某个端口并等待,直到您在该端口上收到一些命令:

ServerSocket socket = new ServerSocket(4444);
while (true) {
  Socket clientSocket = socket.accept();
  // get input stream, etc.
  // if(STOP keywoard read) break
}

What you definitly can do is a loop something like this:

while (true) {
  Thread.sleep(1000);
}

And if you wan't to stop the process you just kill it. Not an elegant solution, however.

Better would be, to listen on some port and wait till you get some command on that port:

ServerSocket socket = new ServerSocket(4444);
while (true) {
  Socket clientSocket = socket.accept();
  // get input stream, etc.
  // if(STOP keywoard read) break
}
追我者格杀勿论 2024-09-15 10:55:37
public class Test extends Thread {

    private static Test thread1, thread2, thread3; //static added since tested from main()

    public static void main(String... arguments){
    try{    
        thread1 = new Test();
        thread2 = new Test();
        thread3 = new Test();
        // Add Names
        thread1.setName("A");
        // Add Sleep
        thread2.sleep(2000); //in milisecs - here it is 2sec
        // Add priority
        thread3.setPriority(Thread.MAX_PRIORITY);

        // Infinite loop
        while(true){    
            thread1.start();
            thread2.start();
            thread3.start();    
        }
    }catch(Throwable t){
        System.err.println(t.getMessage());
    }
}

    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}
public class Test extends Thread {

    private static Test thread1, thread2, thread3; //static added since tested from main()

    public static void main(String... arguments){
    try{    
        thread1 = new Test();
        thread2 = new Test();
        thread3 = new Test();
        // Add Names
        thread1.setName("A");
        // Add Sleep
        thread2.sleep(2000); //in milisecs - here it is 2sec
        // Add priority
        thread3.setPriority(Thread.MAX_PRIORITY);

        // Infinite loop
        while(true){    
            thread1.start();
            thread2.start();
            thread3.start();    
        }
    }catch(Throwable t){
        System.err.println(t.getMessage());
    }
}

    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文