静态线程分析:好主意?

Mar*_*ers 27 java multithreading static-analysis event-dispatch-thread

我帮助维护和构建一个相当大的Swing GUI,有很多复杂的交互.我经常发现自己修复了由于某些其他竞争条件导致事情进入奇怪状态的错误.

随着代码库变大,我发现通过文档指定哪些方法具有线程限制已经不那么一致了:最常见的是必须在Swing EDT上运行的方法.类似地,知道并提供静态感知将是有用的,其中(我们的自定义)侦听器通过规范在EDT上被通知.

因此,我认为这应该可以使用注释轻松实施.请注意,至少存在一个静态分析工具CheckThread,它使用注释来完成此任务.它似乎允许你声明一个方法被限制在一个特定的线程(最常见的是EDT),并将标记尝试调用该方法的方法,而不会将自己声明为局限于该线程.

所以从表面上看,这似乎是对源和构建周期的低痛苦,巨大收益.我的问题是:

  • 对于使用CheckThread或类似库来强制执行线程约束的人来说,是否有任何成功案例?任何失败的故事? 为什么成功/失败?
  • 这在理论上是好的吗? 有理论上的缺点吗?
  • 这在实践中是好的吗? 这值得么? 它提供了什么样的价值?
  • 如果它在实践中有效,那么支持这个的好工具是什么? 我刚刚找到了CheckThread,但承认我并不完全确定我在寻找其他工具来做同样的事情.

我知道它是否适合我们取决于我们的情况.但是我从来没有听说过人们在实践中使用过这样的东西,说实话,它似乎并没有从一些普通的浏览中获得太多.所以我想知道为什么.

Ira*_*ter 8

这个答案更侧重于你的问题的理论方面.

从根本上说,你是在做一个断言:"这种方法只在某些线程下运行".这个断言与你可能做的任何其他断言没有什么不同("该方法只接受参数X小于17的整数").问题是

  • 这些断言来自何处?
  • 静态分析仪可以检查它们吗?
  • 你在哪里得到这样的静态分析仪?

大多数此类断言必须来自软件设计者,因为他们是唯一了解意图的人.传统的术语是"按合同设计",尽管大多数DBC方案仅仅是当前的程序状态(C的断言)它们应该真正超越程序的过去和未来状态("时间断言"),例如,"这个例程将分配一个存储块,最终一些代码将解除分配".人们可以构建试图确定断言是什么的工具(例如,Engler的断言归纳工作;其他人已经在这方面做了工作).这很有用,但误报是一个问题.实际上,要求设计人员编写这样的断言似乎并不特别繁琐,而且是非常好的长期文档.是否使用特定的"契约"语言构造或if语句编写此类断言("如果Debug && Not(断言))然后Fail();")或者在注释中隐藏它们实际上只是一个方便的问题.当语言允许直接编码这样的断言时它很好.

静态检查这些断言很困难.如果您只使用当前状态,静态分析器几乎必须对整个应用程序进行完整的数据流分析,因为满足断言所需的信息可能来自应用程序另一部分创建的数据.(在你的情况下,"内部EDT"信号必须来自分析应用程序的整个调用图,以查看是否有任何调用路径从一个不是EDT线程的线程导致该方法).如果使用时态属性,静态检查还需要某种状态空间验证逻辑; 这些目前仍然是研究工具.即使使用所有这些机器,静态分析仪通常也必须在它们的平均值中保持"保守"; 如果他们能'

你在哪里得到这样的分析仪?鉴于所需的所有机器,它们很难建造,所以你应该期待它们很少见.如果有人建了一个,很棒.如果不是......作为一般规则,您不希望自己从头开始.最好的长期希望是拥有可用于构建此类分析仪的通用程序分析机制,以分摊构建所有基础架构的成本.(我构建了程序分析器工具基础;请参阅我们的DMS软件重新设计工具包).

使构建静态分析器"更容易"的一种方法是限制它们处理的情况以缩小范围,例如CheckThread.我希望CheckThread能够完成目前的工作,而且不太可能变得更强大.

"断言"宏和其他此类动态"当前状态"检查很受欢迎的原因是它们实际上可以通过简单的运行时测试来实现.这很实用.这里的问题是你可能永远不会行使导致条件失败的路径.因此,对于动态分析,没有检测到的故障并不是正确性的真实证据.还是感觉很好.

底线:静态分析仪和动态分析仪各有其强度.