【问题标题】:Why is this conditional statement never executing?为什么这个条件语句永远不会执行?
【发布时间】:2016-08-04 21:31:22
【问题描述】:

我正在阅读 Oracle 发布的“Java 教程”,但我不确定为什么我无法从“并发”一章中获取此示例中的条件语句来执行:

if ((System.currentTimeMillis() - startTime > patience) &&
                msgThread.isAlive())

startTime 变量在上面初始化为:

long startTime = System.currentTimeMillis();

耐心变量可以是硬编码值(1 小时)或作为命令行参数传入的值(以秒为单位)。

    long patience = 1000 * 60 * 60; // initially 1 hour of patience

    // if there is a command-line arg
    if (args.length > 0) {
        try {
            // takes command-line arg as seconds
            patience = Long.parseLong(args[0]) * 1000;
        }
        catch (NumberFormatException e) {
            System.err.println("Invalid commmand-line argument, " +
                "terminating...");
            System.exit(1);
        }
    }

问题是,当我使用各种命令行参数运行程序时(即使我传入 1,它应该在 1 秒后结束,我得到的响应也没有区别!),他们都没有真正得到条件语句为真,这将中断 msgThread 并在屏幕上打印一条消息:

        // if the amount of time passed is more than patience and the
        // thread is still alive
        if ((System.currentTimeMillis() - startTime > patience) &&
            msgThread.isAlive()) {

            // "tired of waiting" to threadMessage
            threadMessage("Tired of waiting, ending thread.");
            // interrupt the thread
            msgThread.interrupt();
            // wait indefinitely for it to finish
            msgThread.join();
        }

以下是我使用 1 秒命令行参数运行时的控制台输出示例:

这里是代码的完整副本,任何理解这些结果的帮助将不胜感激!

/*
*   This program is from Chapter 13 of "The Java Tutorial". It demonstrates
*   some basic Thread funtionality by displaying 4 different messages
*   4 seconds apart in one Thread, while the other thread periodically
*   checks the total run time of the application to see if it has passed
*   a patience threshold, which is hard-coded as 1 hour but can be 
*   input by the user as a commmand-line arg in seconds. If the patience
*   threshold is reached, the main thread interrupts the message thread
*   and displays "finally!"
*/

public class SimpleThreads {
    /* 
    *  Display a message preceded by the name of the current thread.
    *  This will be called periodically throughout the program to
    *  show where we are in the app
    */
    public static void threadMessage(String message) {
        String threadName = Thread.currentThread().getName();
        System.out.format("%s: %s%n", threadName, message);
    }

    /*
    *   Private nested class that will be the Runnable object. The
    *   run() method will be called when a Thread starts execution.
    */
    private static class MessageLoop implements Runnable {
        /*
        *   Prints a message to the console every four seconds.
        *   There are 4 messages total. If interrupted, says so!.
        */
        @Override
        public void run() {
            String[] message = {"msg1", "msg2", "msg3", "msg4"};
            try {
                for (int i = 0; i < message.length; i++) {
                    Thread.sleep(4000); // throws exception if interrupted
                    threadMessage(message[i]);
                }
            }
            catch (InterruptedException e) {
                threadMessage("I wasn't done!");
            }
        }
    }

    /*
    *   Gets the amount of time (patience) that the user will wait for the
    *   MessageLoop classes thread to complete. Starts the MessageLoop
    *   Thread and tracks the total time it runs. If it runs more than
    *   the patience allows for, the MessageLoop thread will be 
    *   interrupted.
    */
    public static void main(String[] args) throws InterruptedException {

        long patience = 1000 * 60 * 60; // initially 1 hour of patience

        // if there is a command-line arg
        if (args.length > 0) {
            try {
                // takes command-line arg as seconds
                patience = Long.parseLong(args[0]) * 1000;
            }
            catch (NumberFormatException e) {
                System.err.println("Invalid commmand-line argument, " +
                    "terminating...");
                System.exit(1);
            }
        }

        // pass message "Starting MessageLoop thread" to threadMessage
        threadMessage("Starting MessageLoop");
        // get the currentTimeMillis and set as start time (long)
        long startTime = System.currentTimeMillis();

        // create a new Thread and pass it the MessageLoop runnable
        Thread msgThread = new Thread(new MessageLoop());
        // start the thread
        msgThread.start();

        // pass "Waiting for msglp thread to finish" to threadMessage
        threadMessage("Waiting for MessageLoop to finish...");

        // in a loop determined by if the thread is still alive
        while (msgThread.isAlive())

            // wait a max of 1 second for thread to finish
            msgThread.join(1000);

            // if the amount of time passed is more than patience and the
            // thread is still alive
            if ((System.currentTimeMillis() - startTime > patience) &&
                msgThread.isAlive()) {

                // "tired of waiting" to threadMessage
                threadMessage("Tired of waiting, ending thread.");
                // interrupt the thread
                msgThread.interrupt();
                // wait indefinitely for it to finish
                msgThread.join();
            }

        // "finally" to threadMessage
        threadMessage("Finally!");
    }
}

【问题讨论】:

  • 现在也可以在 run 方法中使用增强的 for 循环:for (String aMessage : message) {

标签: java multithreading concurrency conditional


【解决方案1】:
   while (msgThread.isAlive()) msgThread.join(1000);

您可能在一段时间后忘记了输入 {。 现在,无论如何,您都在等待线程完成。

试试:

    // in a loop determined by if the thread is still alive
    while (msgThread.isAlive()) {

        // wait a max of 1 second for thread to finish
        msgThread.join(1000);

        // if the amount of time passed is more than patience and the
        // thread is still alive
        if ((System.currentTimeMillis() - startTime > patience) &&
            msgThread.isAlive()) {

            // "tired of waiting" to threadMessage
            threadMessage("Tired of waiting, ending thread.");
            // interrupt the thread
            msgThread.interrupt();
            // wait indefinitely for it to finish
            msgThread.join();
        }
    }

【讨论】:

  • 天哪,我今天看代码太久了……愚蠢的错误,感谢您发现它!出于某种原因,我不能再接受 5 分钟的答案,但我会尽快接受。
  • 在与原始来源进行比较时,我也注意到了 type-o。我想可能就是这样。
猜你喜欢
  • 1970-01-01
  • 2015-01-18
  • 1970-01-01
  • 1970-01-01
  • 2012-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多