替代java中的synchronized块

时间:2012-07-25 12:15:26

标签: java multithreading synchronization thread-safety thread-synchronization

我只使用以下代码进行一次保证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语句)

6 个答案:

答案 0 :(得分:11)

使用AtomicReference

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)

所以根据我的理解,你需要一个单身人士:

  1. 简短,易于实施/理解。
  2. 仅在调用doProcess时初始化。
  3. 我建议使用嵌套类进行以下实现:

    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。如果你想要一个没有ifsynchronized关键字的示例,我会以Initialize the static variable during declaration.方式向您展示。

public class MyClass{

  private static MyClass unique = new MyClass();

  private MyClass{}

  public static MyClass getInstance(){

      return unique;

  }

 }