开发者

java thread pool keep running

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 happeni开发者_运维技巧ng? I'm sure there are several options, some more naive than others (while true loops come to mind). Any ideas? Thanks.


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.


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();
   }


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();
        }
    }
}


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
}


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());
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜