繁体   English   中英

如何在 Java 7 中实现“像承诺一样”的线程同步系统?

[英]How can I implement a "promise like" thread-synchronization system in Java 7?

我有一个获取全局对象的静态方法:

public static Application getApplication() {
    // ...
}

由于 I/O, Application实例的创建需要时间,因此我们在单独的线程中创建它。 在此期间,其他线程可能会尝试调用getApplication() 我想要的行为是让这些线程阻塞,直到创建全局Application实例。 我基本上想要这种结构的东西:

private static Application application;
private static PromiseLikeLock lock = new PromiseLikeLock();

public static Application getApplication() {
    lock.await();
    return application;
}

// In thread:
application = new Application();
lock.release();

具有以下行为:

  1. lock对象是一个状态机,它要么被锁定,要么释放 它开始锁定。
  2. 当一个线程调用lock.wait() ,如果锁被释放,它会照常进行,否则它会阻塞。
  3. lock.release()被调用时,锁被释放并且所有在调用wait()阻塞的线程都会解除阻塞。

我认为这应该做到......使用Java 7 API。

FutureTask<Application> ft =
       new FutureTask<>(new Callable<Application>() {
                             public Application call() {
                                  return new Application();
                             }});
new Thread(ft).start();

// Somewhere else / later on
Application app = ft.get();

FutureTaskjavadoc描述如下:

可取消的异步计算。 此类提供Future的基本实现,具有启动和取消计算、查询以查看计算是否完成以及检索计算结果的方法。 计算完成后才能检索结果; 如果计算尚未完成, get方法将阻塞。 ....

FutureTask可用于包装CallableRunnable对象。 由于FutureTask实现了Runnable ,因此可以将FutureTask提交给Executor执行。

您也可以将其传递给一次性Thread


但坦率地说,你不应该为 Java 7 编写新代码。如果你使用 Java 8 语言特性,上面的代码会更清晰; 例如Application::new

这看起来很像单例模式,可以使用具有单个值的枚举来实现:

enum Application{
  INSTANCE;


  private Application(){
    //initialize
  }
  //other methods/fields can go here...
}

初始化将在第一次加载类时发生。 类加载器保证线程安全,即它只会调用构造函数一次,其他访问 Application.INSTANCE 的类将被阻塞,直到它完全加载。

这与 FutureTask 解决方案的区别在于没有启动单独的线程,初始化是在实际使用它的第一个线程中调用的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM