2010-07-04 79 views
2

这是一个比特定问题更通用的问题。我试图让多线程环境保持活动状态,以便我可以提交任务并运行它们。我想在没有在Web服务器或应用程序服务器中执行的麻烦的情况下执行此操作。这个想法是为此使用java线程池,但问题在于,池直到我的主方法完成时才保持打开状态,之后显然它关闭并且程序结束。我怎样才能防止这种情况发生?我确信有几个选择,比其他人更天真(而真正的循环想到)。 任何想法?谢谢。java线程池继续运行

+0

你想主要终止和你的线程继续运行? – 2010-07-04 13:11:37

+0

你如何向你的应用程序提交任务? – naikus 2010-07-04 14:33:14

+0

你不是在制作守护线程吗? – 2010-07-05 16:19:27

回答

1

如何您的任务被接受?

在很多情况下,我看到有1个线程正在等待或轮询任务并将其传递。该线程将保持应用程序的活动状态,并且还可以等待某个标志关闭应用程序,等待当前作业完成并清理。总而言之,我发现处理这些应用程序生命周期事件的麻烦已经超过了部署到像Jetty这样的简单容器的麻烦,这一点很容易达成。特别是对于在后台运行的东西,我发现在几个愚蠢的JSP页面中有很多价值来验证它仍然在工作(与我们的自动监视集成)并获取一些统计信息。

-1

什么你definitly可以做的是一个循环是这样的:

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

如果你wan't停止过程中,你杀了它。然而,这不是一个优雅的解决方案

更好的方式是,听一些端口上,等到您在该端口上得到一些命令:

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

以下是我为另一篇文章撰写的示例,该文章允许您在另一个线程上提供可以发布消息的线程池。 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(); 
     } 
    } 
} 
+0

至少,字段'ServerThread#stop'需要声明* volatile *。 – seh 2010-07-04 13:44:03

+0

@seh并非如此,我只有一个可以在我的示例中写入的线程和一个可以从中读取的线程。我不关心线程安全性,也不关心它被缓存了一段时间。无论如何,读取或写入布尔值是原子。 – 2010-07-04 14:01:46

+1

你的位置的重要部分不关心,如果“[布尔字段]被缓存一段时间”。它可以被缓存 - 因此对于想要“中断”的线程永远不可见。尽管分配布尔型字段可能会“原子地”发生 - 因为没有读者可以看到“部分值” - 跨线程边界的写入*传播受到很大的影响,您不应该举一个例子取决于传播而不注意或消除漏洞。 – seh 2010-07-04 18:18:02

0

这是我在一些程序中在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(); 
    } 
-1
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()); 
    } 
}