我带了this code:
28 public static void main(String[] args) throws IOException {
29 HttpServer httpServer = startServer();
30 System.out.println(String.format("Jersey app started with WADL available at "
31 + "%sapplication.wadl\nTry out %shelloworld\nHit enter to stop it...",
32 BASE_URI, BASE_URI));
33 System.in.read();
34 httpServer.stop();
35 }
第33行“System.in.read()”是否意味着它会阻塞直到有输入?使用UNIX rc脚本启动Java应用程序时这是否也有效 - 不是从命令行手动启动的?
我想编写一个Java应用程序来监听HTTP连接。系统引导时将自动启动应用程序(使用UNIX rc脚本)。这意味着应用程序将持续运行 - 理论上永远,直到有目的地停止。在Java main()方法中实现它的最佳方法是什么?
答案 0 :(得分:22)
它看起来像一个奇怪的黑魔法,但是以非常优雅的方式完成了这个技巧
Thread.currentThread().join();
因此,当前线程main
等待join()
线程main
,这本身就是结束。僵持。
当然,被阻止的线程不能是守护程序线程。
答案 1 :(得分:14)
将main
方法保留在Java中 not 会自动结束该程序。
如果没有正在运行的非守护程序线程,则存在JVM。默认情况下,唯一的非守护程序线程是主线程,它在您离开main
方法时结束,因此停止JVM。
所以要么不要结束主线程(不要让main
方法返回)或创建一个永不返回的新非守护进程线程(至少在你希望 JVM结束之前)。
由于该规则实际上非常明智,通常是这种线程的完美候选者。对于HTTP服务器,例如,它可以是实际接受连接的线程,并将它们移交给其他线程以进行进一步处理。只要该代码正在运行,即使main
方法早已完成运行,JVM也将继续运行。
答案 2 :(得分:5)
@Joachim的回答是正确的。
但是如果(由于某种原因)你仍然想要无限期地阻止主方法(没有轮询),那么你可以这样做:
public static void main(String[] args) {
// Set up ...
try {
Object lock = new Object();
synchronized (lock) {
while (true) {
lock.wait();
}
}
} catch (InterruptedException ex) {
}
// Do something after we were interrupted ...
}
由于锁定对象仅对此方法可见,因此notify
无法wait()
,因此main
调用将不会返回。但是,其他一些线程仍然可以通过中断它来取消阻塞{{1}}线程。
答案 3 :(得分:1)
while (true) { ... }
应该会持续很长时间。当然,你最终必须想出一些阻止它的方法。
一个常见的诀窍是拥有一些volatile boolean running = true
,然后让主循环为while (running) { ... }
并定义线程设置running = false
的一些标准。
答案 4 :(得分:1)
回到主题,这正是我想要的。顺便说一下这个很棒的tutorial给了我很多帮助。
Main.java
public class Main {
public static void main(String args[]) {
ChatServer server = null;
/*if (args.length != 1)
System.out.println("Usage: java ChatServer port");
else*/
server = new ChatServer(Integer.parseInt("8084"));
}
}
和ChatServer.java类扩展了Runnable
public class ChatServer implements Runnable
{ private ChatServerThread clients[] = new ChatServerThread[50];
private ServerSocket server = null;
private Thread thread = null;
private int clientCount = 0;
public ChatServer(int port)
{ try
{ System.out.println("Binding to port " + port + ", please wait ...");
server = new ServerSocket(port);
System.out.println("Server started: " + server);
start(); }
catch(IOException ioe)
{
System.out.println("Can not bind to port " + port + ": " + ioe.getMessage()); }
}
public void start() {
if (thread == null) {
thread = new Thread(this);
thread.start();
}
}
.... pleas continue with the tutorial
因此,在主方法中,实例化了一个Runnable和一个新的Thread,如图所示
public void start() {
正在使用runnable进行实例化。
这就是JVM在您退出项目或调试器之前继续执行该过程。
顺便说一句,就像Joachim Sauer在他的回答中所说的一样。
答案 5 :(得分:-1)
我们也可以使用ReentrantLock并在其上调用wait()来实现相同目的:
public class Test{
private static Lock mainThreadLock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
System.out.println("Stop me if you can");
synchronized (mainThreadLock) {
mainThreadLock.wait();
}
}