当前位置: 首页 > 面试题库 >

将代码从使用计时器移植到Scheduledexecutorservice

颛孙飞
2023-03-14
问题内容

我正在尝试将代码从使用Java
计时器移植到使用Scheduledexecutorservice

我有以下用例

class A {

    public boolean execute() {
         try {
              Timer t = new Timer();
              t.schedule (new ATimerTask(), period, delay);
         } catch (Exception e) {
              return false;
         }
    }

}


class B {

    public boolean execute() {
         try {
              Timer t = new Timer();
              t.schedule (new BTimerTask(), period, delay);
         } catch (Exception e) {
              return false;
         }
    }

}

我应该用ScheduledExecutorService替换A类和B类中的Timer实例,并使ATimerTask和BTimerTask类成为Runnable类,例如

class B {

    public boolean execute() {
         try {
              final ScheduledExecutorService scheduler = 
   Executors.newScheduledThreadPool(1);

              scheduler.scheduleWithFixedDelay (new BRunnnableTask(), period, delay);
         } catch (Exception e) {
              return false;
         }
    }

}

这样对吗。

编辑:移植的主要动机之一是因为在TimerTask中引发的运行时异常会杀死一个线程,因此无法对其进行进一步调度。我想避免这种情况,以便即使我有运行时异常,该线程也应继续执行而不停止。


问题答案:

注意:您执行此操作的方式将泄漏线程!

如果您的课程B将保留下来,并且 每个实例 最终 将被关闭或关闭或释放,那么我将这样做:

class B {
  final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

  public boolean execute() {
    try {
      scheduler.scheduleWithFixedDelay(new BRunnnableTask(), period, delay);
      return true;
    } catch (Exception e) {
      return false;
    }
  }

  public void close() {
    scheduler.shutdownNow();
  }
}

如果您不会在每个实例上进行这种清理,那么我会这样做:

class B {
  static final ScheduledExecutorService SCHEDULER = Executors.newCachedThreadPool();

  public boolean execute() {
    try {
      SCHEDULER.scheduleWithFixedDelay(new BRunnnableTask(), period, delay);
      return true;
    } catch (Exception e) {
      return false;
    }
  }
}

ExecutorService您在代码中分配的每个分配都会分配一个Thread。如果您制作了很多类实例,B则每个实例都会分配一个Thread。如果这些不能迅速收集到垃圾,那么您可能最终会分配成千上万个线程(但未使用,只是分配了),并且可能使整个服务器崩溃,使机器上的每个进程都挨饿,而不仅仅是您自己的JVM。我已经看到它在Windows上发生,并且我希望它也可以在其他OS上发生。

当您不打算在单个对象实例上使用生命周期方法时,静态缓存线程池通常是一种安全解决方案,因为您只会保留实际 运行的
线程数,而不会为创建的每个实例分配一个线程尚未收集垃圾。



 类似资料:
  • " Life is pleasant. Death is peaceful. It’s the transition that’s troublesome. " — Isaac Asimov (attributed) 概述 几乎所有的Python 2程序都需要一些修改才能正常地运行在Python 3的环境下。为了简化这个转换过程,Python 3自带了一个叫做2to3的实用脚本(Utility S

  • null Edit2:为了一致性和正确性,将填充重命名为iVector。

  • 问题内容: 我在使用SQLite的应用程序中曾经存储8-10列。我曾经根据任意多个这些属性的组合来检索数据。现在我想移植到Redis。所以我正在为此开发一个测试应用程序。 但是我无法考虑如何设计我的Redis系统,使我能够基于任何这些属性来检索数据。你们有什么建议/经验吗? 问题答案: 我认为最好的建议是从RDBMS移植到Redis时避免遵循关系模型。除模型之外,一个重要的区别是着眼于数据访问路径

  • 这里是一个JavaScript部分,它用AES加密解码字符串 我试图用python编写一个类似的解码函数,并导入AES。 谁能帮我做这个吗。我无法找出js到python的所有等效代码。 我查了这个页面Python AES解密例程(代码帮助)和 AES-加密与加密(node-js)/解密与Pycrypto(python) 不确定他们的代码是否与我这里的js相似 这在python中是什么意思 我从另一

  • 问题内容: 我已经尝试将invRegex.py移植到node.js实现了一段时间,但是我仍然在努力。多亏了ret.js标记生成器,我已经有了正则表达式分析树,并且运行良好,但是以内存高效的方式实际生成和连接所有不同元素对我来说是非常具有挑战性的。为简单起见,可以说我有以下正则表达式: 喂养到产生下列输出( tabbified 取更小的空间): 考虑到我能够获取每个单独的令牌并产生所有有效的单独输出

  • 一般说来, 可移植性并非汇编语言的长项。 然而, 写出能够在不同平台上执行的汇编代码仍然是可能的事情, 特别是在使用 nasm 的时候。 我曾经写过一个汇编语言函数库, 可以在 Windows® 或 FreeBSD 这样不同的操作系统下进行汇编。 所以, 让你的代码在两种不同但是又基于相似的结构的平台上运行是完全可能的。 比如, FreeBSD 是 UNIX® 操作系统,Linux 是类UNIX