在Java中使用Thread.currentThread()。join()

时间:2016-01-06 08:55:27

标签: java multithreading jersey jersey-2.0

以下代码取自Jersey项目中的示例。请参阅here

public class App {

    private static final URI BASE_URI = URI.create("http://localhost:8080/base/");
    public static final String ROOT_PATH = "helloworld";

    public static void main(String[] args) {
        try {
            System.out.println("\"Hello World\" Jersey Example App");

            final ResourceConfig resourceConfig = new ResourceConfig(HelloWorldResource.class);
            final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(BASE_URI, resourceConfig, false);
            Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
                @Override
                public void run() {
                    server.shutdownNow();
                }
            }));
            server.start();

            System.out.println(String.format("Application started.\nTry out %s%s\nStop the application using CTRL+C",
                    BASE_URI, ROOT_PATH));

            //////////////////////////////
            Thread.currentThread().join();
            //////////////////////////////

        } catch (IOException | InterruptedException ex) {
            //
        }

    }
}

我理解除了使用Thread.currentThread().join();之外发生了什么。

我是一个Java新手,我的理解是这将阻止当前线程(在本例中为主线程)的执行,并有效地使其死锁。即它将导致当前(主)线程阻塞,直到当前(主)线程结束,这将永远不会发生。

这是对的吗?如果是这样,为什么会出现?

4 个答案:

答案 0 :(得分:14)

Vehicle永远阻止当前线程。在您的示例中,这会阻止Thread.currentThread().join()退出,除非程序被终止,例如在Windows上使用CTRL + C.

如果没有该行,主方法将在服务器启动后立即退出。

另一种方法是使用main

答案 1 :(得分:4)

这是一个常见的误解,如果$sql = "UPDATE tableName set `comma_sep_col` = IF(`comma_sep_col` = '','$user_id',CONCAT(`comma_sep_col`, ',', '$user_id')) WHERE find_in_set('$user_id',`comma_sep_col`) = 0 AND `task_id` = $task_id"; 线程退出,程序将退出。

仅当没有运行非守护程序线程时才会出现这种情况。这可能在这里是正确的,但通常更好的恕我直言,使主要的后台线程“等待”非dameon并让主线程退出时它没有任何事情要做。我看到开发人员将main包裹在无限循环中。等

答案 2 :(得分:1)

这是一个例子。它不是一个非常好的。

他们试图向您展示如何制作永久运行的线程。

Thread.currentThread().join();是一个需要永远完成的声明。你应该用你自己的代码替换它,这些代码永远运行,并且可能会做一些有用的事情。

答案 3 :(得分:-1)

我知道这是一个Java问题,但是对于那些来到这里并在Kotlin居住的人,我建议您不要使用问题中提到的诱捕解决方案。

在您自己的线程上等待是一项阻塞操作,无法进行转义。在Kotlin社区中,我注意到了一种编写可传达目的的代码的趋势,在这种情况下,目的似乎并不取决于阻塞线程。看起来更像是要等待其他事情发生。

对于将关机控制传递给关机程序的必要性,我有一个快速解决方案,一旦系统发送终止信号,该程序便会启动。由于有锁存器,该解决方案将仅等待信号传播。主用户线程(与守护程序线程相对)将继续运行,并允许拆卸程序在最终完成之前运行。

    fun main(): Int {
        // your server bootstrapping code here ...
        server.start() // Start the thread
        // prepare a latch to wait on (one countdown)
        val applicationLatch = CountDownLatch(1)
        // hook up the termination routines
        Runtime.getRuntime().addShutdownHook(Thread {
            server.stop()
            applicationLatch.countDown()
        })
        // wait for the shutdown hook to free the latch
        applicationLatch.await()
        // anything else you want to clean up can go here ...
        return 0
    }

我希望有人对此发表评论,看看它是否是一个值得解决的方案。

免责声明:此代码不处理重要的错误控制详细信息。只是一个简单的例子