我只使用以下代码进行一次保证startTime
变量设置:
public class Processor
{
private Date startTime;
public void doProcess()
{
if(startTime == null)
synchronized(this)
{
if(startTime == null)
{
startTime = new Date();
}
}
// do somethings
}
}
我将保证通过此代码仅为任意数量的调用process
方法调用实例化一次变量。
我的问题是:
我的代码是否有更简洁的替代方法? (样本删除if
& synchronized
语句)
答案 0 :(得分:11)
public class Processor {
private final AtomicReference<Date> startTime = new AtomicReference<Date>();
public void doProcess() {
if (this.startTime.compareAndSet(null, new Date())) {
// do something first time only
}
// do somethings
}
}
答案 1 :(得分:10)
根据您的评论,您可以使用AtomicReference
firstStartTime.compareAndSet(null, new Date());
或AtomicLong
firstStartTime.compareAndSet(0L, System.currentTimeMillis());
我会用
private final Date startTime = new Date();
或
private final long startTime = System.currentTimeMillis();
答案 2 :(得分:4)
您的代码是所谓的“双重检查锁定”的示例。请阅读此article。它解释了为什么这个技巧在java中不起作用,尽管它非常聪明。
答案 3 :(得分:2)
总结其他海报已经解释过的内容:
private volatile Date startTime;
public void doProcess()
{
if(startTime == null) startTime = new Date();
// ...
}
对你来说足够简洁?
答案 4 :(得分:2)
所以根据我的理解,你需要一个单身人士:
doProcess
时初始化。我建议使用嵌套类进行以下实现:
public class Processor {
private Date startTime;
private static class Nested {
public static final Date date = new Date();
}
public void doProcess() {
startTime = Nested.date; // initialized on first reference
// do somethings
}
}
答案 5 :(得分:0)
1 您使用的内容称为double checked locking
。
2. 还有另外两种方法可以做到这一点
- Use synchronized on the Method
- Initialize the static variable during declaration.
3。如果你想要一个没有if
和synchronized
关键字的示例,我会以Initialize the static variable during declaration.
方式向您展示。
public class MyClass{
private static MyClass unique = new MyClass();
private MyClass{}
public static MyClass getInstance(){
return unique;
}
}