我怎样才能实现一个;“像承诺一样”;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。因此,将其声明为枚举而不是类会改变运行时处理它的方式?如果您将其声明为带有“静态初始化块”的普通类,它的处理方式或多或少与枚举相同,但枚举的语法比静态初始化块清晰得多,尤其是当您只需要它的一个实例时。