我怎样才能实现一个;“像承诺一样”;Java7中的线程同步系统?

我怎样才能实现一个;“像承诺一样”;Java7中的线程同步系统?,java,android,multithreading,java-7,Java,Android,Multithreading,Java 7,我有一个获取全局对象的静态方法: public static Application getApplication() { // ... } 由于I/O的原因,应用程序实例需要时间来创建,因此我们在单独的线程中创建它。在此期间,其他线程可能会尝试调用getApplication()。我想要的行为是阻止这些线程,直到创建了全局应用程序实例。我基本上想要这种结构的东西: private static Application application; private static Promi

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

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

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();
具有以下行为:

  • lock
    对象是一个被锁定或释放的状态机。它开始是锁着的
  • 当线程调用
    lock.wait()
    时,如果锁被释放,它将正常进行,否则它将阻塞
  • 调用
    lock.release()
    时,锁被释放,所有线程在调用
    wait()
    unblock时阻塞

  • 我想这应该可以。。。。使用Java7API

    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();
    
    FutureTask的
    FutureTask
    描述如下:

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

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

    您也可以将其传递给一个单独使用的
    线程



    但坦率地说,您不应该为Java7编写新代码。如果您使用Java8语言特性,则上述内容更清晰;e、 g.
    Application::new

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

    enum Application{
      INSTANCE;
    
    
      private Application(){
        //initialize
      }
      //other methods/fields can go here...
    }
    
    初始化将在类首次加载时发生。classloader保证线程安全,即它只调用构造函数一次,其他访问Application.INSTANCE的类将被阻止,直到完全加载为止


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

    @pdem没错,但它们不符合我的条件。它们违反了第(2)点。好吧,为什么是java7?我建议CompletableFuture,它来自Java8,我倾向于将我的所有应用程序迁移到java11@pdem硬件强制(Android在专用硬件上)。实际上,我要重新表述这个问题-我使用wait and notify的实现不起作用,因此,我很乐意回答一个家庭滚动实现。@ JackM,您应该考虑花些时间阅读包<代码> java。UTI.Outlook < /Calp> WoAh。因此,将其声明为枚举而不是类会改变运行时处理它的方式?如果您将其声明为带有“静态初始化块”的普通类,它的处理方式或多或少与枚举相同,但枚举的语法比静态初始化块清晰得多,尤其是当您只需要它的一个实例时。