这是一个通用问题,而不是特定问题。我正在尝试保持活动的多线程环境,以便我可以只提交任务并运行它们。我想这样做,没有在Web服务器或应用程序服务器中执行的麻烦。我的想法是使用一个java线程池,但这里的问题是池在我的main方法完成之前保持打开状态,之后很明显它会关闭并且程序结束。我怎样才能防止这种情况发生?我确信有几种选择,有些比其他选择更天真(而真正的循环会浮现在脑海中)。 有任何想法吗?谢谢。
答案 0 :(得分:1)
您的任务如何被接受?
在很多情况下,我看到有1个线程正在等待或轮询任务并传递它们。该线程将使您的应用程序保持活动状态,还可以等待某个标志关闭应用程序并等待当前作业完成并清理。
总而言之,我发现处理这些应用程序生命周期事件的麻烦超出部署到像Jetty这样的简单容器的麻烦很容易实现。特别是对于在后台运行的东西,我发现在几个愚蠢的JSP页面中有很多价值,以确认它仍在工作(与我们的自动监控集成)并获得一些统计数据。
答案 1 :(得分:0)
这是我为另一篇文章写的一个示例,它允许您在另一个可以发布消息的线程上提供一个线程池。 main()创建Threads,并允许您在需要时停止Thread。要阻止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();
}
}
}
答案 2 :(得分: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();
}
答案 3 :(得分:-1)
你明确可以做的是这样的循环:
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
}
答案 4 :(得分:-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());
}
}