[英]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();
具有以下行为:
lock
对象是一个状态机,它要么被锁定,要么被释放。 它开始锁定。lock.wait()
,如果锁被释放,它会照常进行,否则它会阻塞。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();
FutureTask
的javadoc描述如下:
可取消的异步计算。 此类提供
Future
的基本实现,具有启动和取消计算、查询以查看计算是否完成以及检索计算结果的方法。 计算完成后才能检索结果; 如果计算尚未完成,get
方法将阻塞。 ....
FutureTask
可用于包装Callable
或Runnable
对象。 由于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.