2010-07-04 2 views
2

Это скорее общий вопрос, чем конкретный вопрос. Я пытаюсь иметь многопоточную среду, которая остается активной, чтобы я мог просто отправлять задания и запускать их. Я хочу сделать это без хлопот на веб-сервере или сервере приложений. Идея состояла в том, чтобы использовать для этого пул потоков java, но проблема здесь заключается в том, что пул остается открытым только до тех пор, пока мой основной метод не завершится, после чего, очевидно, он закроется и программа завершится. Как я могу предотвратить это? Я уверен, что есть несколько вариантов, некоторые более наивные, чем другие (в то время как верные петли приходят на ум). Любые идеи? Благодарю.java thread pool keep running

+0

вы хотите главным прекратить и вашу тему продолжать работать ли? –

+0

Как вы отправляете задания в свое приложение? – naikus

+0

Вы не делаете темы демона, не так ли? –

ответ

1

Как ваши задачи принимаются?

Во многих случаях я видел, что из задач выполнялось 1 потоковое ожидание или опрос и передача их. Этот поток будет поддерживать ваше приложение в ожидании, а также может ждать появления какого-либо знака для завершения работы приложения и ожидания завершения и очистки текущих заданий.

В целом я нахожу, что точка, с которой легко справляется проблема с этими событиями жизненного цикла приложения, затрудняет развертывание в простой контейнер, такой как Jetty. Особенно для вещей, работающих в фоновом режиме, я нахожу большую ценность в нескольких глупых страницах JSP, чтобы убедиться, что он все еще работает (чтобы интегрироваться с нашим автоматическим мониторингом) и получать некоторые статистические данные.

-1

То, что вы определенно можете сделать это петля-то вроде этого:

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 от завершения, просто исключите процессор.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

+0

@seh Не совсем, у меня есть только один поток, который может писать ему в моем примере и один поток, который можно прочитать из него. Я не забочусь о безопасности Thread и не кешируется какое-то время. Логическое значение является атомарным при чтении или записи в любом случае. –

+1

Важная часть вашей позиции не заботится, если «[булевское поле] кэшируется в течение определенного периода времени». Он может быть кэширован - и, следовательно, не виден нить, которую вы хотите «прерывать» - навсегда.Хотя присвоение логического поля может происходить «атомарно» - в том смысле, что ни один читатель не мог видеть «частичное значение» - * распространение * того, что пишет границы потоков, подвержено значительной свободе, и вы не должны приводить пример в зависимости от этого распространения, не отмечая или не устраняя уязвимость. – seh

0

Вот несколько кодов, которые я вызываю в конце моей основной() в некоторых программах. Если пользователь вводит «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()); 
    } 
}