代码之家  ›  专栏  ›  技术社区  ›  The Grey Ghost

线程正确性的断言或注释

  •  2
  • The Grey Ghost  · 技术社区  · 8 年前

    有没有一些现有的工具可以帮助我做到这一点?

    例如- 断言我的方法正被正确的线程调用 或 某种带有注释的静态检查,类似于@Nullable和@NotNull,用于检测代码何时从错误线程调用方法。

    虽然项目是多线程的,但几乎不需要同步,因为不同的线程不访问相同的对象,它们有自己的实例。 一般来说,有四个线程同时运行

    • 客户
    • 客户端线程=处理用户输入,维护本地 用于渲染的服务器数据的副本/缓存
    • 在服务器和客户端之间
    • Render thread=将本地数据处理为 图形卡

    这些类有时仅用于其中一个线程(例如,用户输入轮询仅用于客户端),有时用于多个线程(如投射物的计算移动同时在客户端和服务器上使用相同的代码以减少感知的延迟)。好几次我从错误的线程调用了一个方法,导致了细微的、不可重复的错误,以及非常严重的显示器屏幕损坏(从我的拳头上)

    到目前为止,我的想法是这样的:

    public void myMethodThatAssumesClientThreadOnly() {
      assert checkThread(CLIENT);
      // can now happily call other client-thread code without fear 
    }
    

    但我更喜欢类似@Nullable的静态检查

    @Thread(CLIENT)
    void myClientMethod() {
      //client-only stuff here
    }
    
    @Thread(SERVER)
    void myServerMethod() {
      //server-only stuff here
    }
    
    @Thread(CLIENT + SERVER)
    void myClientAndMethod() {
      myClientMethod();  // error- server thread might call client method 
    }
    

    不幸的是,作为一个注释新手,我不知道这是简单的还是非常困难的。

    有什么建议吗?我无法想象我是第一个寻找这样东西的人。

    TGG公司

    2 回复  |  直到 8 年前
        1
  •  1
  •   mernst    8 年前

    这个 Checker Framework 允许创建验证程序正确性的编译时静态检查器。它的 GUI Effect Checker 和你想要的一样。以下是摘自 its manual :

    最常见的GUI相关错误之一是无效的UI更新或无效的线程访问:直接从后台线程访问UI。

    如果后台线程访问诸如JPanel之类的UI元素(通过调用JPanel方法或读/写JPanel字段),GUI框架会引发异常,从而终止程序。

    程序员很难记住哪些方法可以在哪些线程上调用。GUI效果检查器解决了这个问题。程序员对每个方法进行注释,以指示是否:

    • 它不访问UI元素(可以在任何线程上运行)。
    • 它可以访问UI元素(并且必须在UI线程上运行)。

    GUI效果检查器静态强制用户界面方法只能从正确的线程调用。

    有一个 paper 讨论了使用GUI效果检查器的案例研究。

    另一种方法是调整 bug finder 保证 没有线程错误。然而,它在实践中是有效的,并且不需要在程序中编写任何注释。

    Lock Checker

        2
  •  1
  •   Solomon Slow    8 年前

    这将断言该方法 foobar() 被正确的线程调用。。。

    SomeType foobar(...) {
        assert(Thread.currentThread() == theCorrectThread);
        ...
    }
    

    foobar() 您设置的呼叫

    Thread theCorrectThread = new Thread(...);
    

    但我更喜欢类似@Nullable的静态检查

    我自己对注释知之甚少。我知道它们可以用于将元信息附加到编译的类,并且我知道程序可以在运行时通过调用 Class 对象,但如果注释可以定义 编译时间 行为,这超出了我的知识范围。