【问题标题】:have method return false if a block of code is taking to long如果代码块需要很长时间,则让方法返回 false
【发布时间】:2013-04-29 02:13:38
【问题描述】:

线程和定时器有问题。我需要这个方法来执行一些代码,但如果代码需要很长时间,该方法应该返回 false。这是我正在做的事情:

    public boolean handShake() {

        java.util.Timer t = new java.util.Timer();
    t.schedule(new java.util.TimerTask() {
            public void run() {
                if (threadSuccess = false) {
                    System.out.println("will kill");
//not sure but this is how I read you should kill threads?
                    Thread t = handShakeThread;
                    handShakeThread = null;
                    t.interrupt();
                    System.out.println("Should have killed thread");
                }
            }
        }, 8000);

        try {
            System.out.println("Going to start threads");

            handShakeThread = new Thread(new HandShakeThread());
//handShakeThread is a field (Threat) and HandShakeThread is a class extending Runnable
            handShakeThread.start();
        System.out.println("Thread started");
            handShakeThread.join();
            System.out.println("finished");
            return threadSuccess;
        } catch (InterruptedException e1) {
            e1.printStackTrace();
            return false;
        }
    }

计时器任务似乎从未被调用。它坐在那里等待和等待。我能做什么?

额外信息: handShakeThread 正在从网络中读取数据。如果成功完成读取,则将字段 threadSuccess 设置为 true。这个想法是,如果从网络读取需要很长时间,则应该有一个超时。这是最好的方法吗?

【问题讨论】:

  • 我建议使用 Java 5+ 并发 API。例如,您可以使用 ExecutorService (docs.oracle.com/javase/6/docs/api/java/util/concurrent/…),它为您提供了一些方法来指定超时。
  • 可能不相关,但是您编写 if(threadSuccess = false)threadSuccess 设置为 false 并且不进入 if 块。你可能想要if(!threadSuccess)
  • 你应该能够为你的网络调用设置一个超时时间——比如在套接字上的setSoTimeout(<time>) 或类似的。

标签: java multithreading timer runnable


【解决方案1】:

尝试将您的 HandShakeThread 重写为 Runnable 并执行类似的操作。如果 Runnable 在 8 秒后没有完成,该方法将返回 false。

public boolean handShake() {
    Runnable handShakeTask = new Runnable() {
        @Override
        public void run() {
            // do network stuff
        }
    };
    ExecutorService executorService = Executors.newFixedThreadPool(1);
    try {
        Future<Boolean> future = executorService.submit(networkTask, true);
        executorService.shutdown();
        return future.get(8, TimeUnit.SECONDS);
    } catch (TimeoutException ex) {
        return false;
    } catch (InterruptedException | ExecutionException e) {
        // handle exception
    } 
}

【讨论】:

  • 感谢您的提示,rolfl。我向 ExecutorService 添加了一个关闭调用。
  • 除非“工作”线程旨在处理被中断,否则它仍会继续运行。幸运的是,在这种情况下,由于 Java 的阻塞 IO 机制表现良好,它可能会起作用
  • 您好,非常感谢,这看起来正是我所需要的。你/有人能解释一下代码是如何工作的吗?对于初学者来说,哪一行告诉 ExecutorService 使用上面的 Runnable?我也没有看到提到 8 秒。还是您仅以 2 秒为例?任何对所用代码行的解释将不胜感激 - 我是线程的初学者。谢谢!!!!
  • .submit 调用告诉 ExecutorService 安排 Runnable。该服务是使用单线程线程池启动的,因此可以相当安全地假设 Runnable 将在您调用 submit 时立即运行。如果你在返回的 Future 上调用 get,它会阻塞你当前的线程,直到进程完成,但是如果你调用 get 时有超时(我不小心把它设置为 2 秒而不是 8 秒)——Future 会抛出 TimeoutException如果到那时该进程仍在运行。这可以防止您的主线程被阻塞,尽管 Runnable 将继续运行。
  • 如果您确实想停止执行可运行的线程,您可以在未来调用 boolean cancel(boolean mayInterruptIfRunning),传入一个 true 值。这将尝试中断线程,但不保证会这样做。
猜你喜欢
  • 2014-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-10
  • 2020-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多