即使通过创建多个类实例调用方法,也可以使方法线程安全

时间:2011-07-21 07:39:01

标签: java thread-safety

我想要有线程保存方法,返回一个唯一的当前Timestamp.Even当同时调用该方法我想获得一个唯一的当前datetime.Even如果通过创建MyClass的多个实例调用此方法我想要它始终是线程安全的

class Myclass{

 Date getUniquetimeStam(){
   synchronized(Myclass.class){
    //return date here 
   }

}

现在,如果我创建2个Myclass实例并且同时调用getUniqueStam,它是否会获得返回单独的日期时间。

4 个答案:

答案 0 :(得分:1)

您无法保证每次通话的唯一时间。但是,如果它没有改变,你可以手动增加它:

private AtomicLong lastTime = new AtomicLong();

long getUniquetimeStam() {
    while (true) { // way of working with atomics, but they are really fast
        long now = System.currentTimeMillis();
        long last = lastTime.get();
        if (last < now) {
            if (lastTime.compareAndSet(last, now))
                return now;
        } else
            return lastTime.incrementAndGet();
    }
}

答案 1 :(得分:0)

您是否可以更改它以在每次通话时返回Date的新实例?

class Myclass {

 Date getUniquetimeStam() {
   new Date();
  }

}

答案 2 :(得分:0)

不,你不能保证。如果您的计算机足够快,那么两个方法调用都可以在相同的毫秒内发生,并生成相同的Date对象。

这里有2个选项:

  1. 使用UUID代替日期。阅读更多相关信息here。每次生成UUID时,都会保证UUID是唯一的 - 因此它是您可以获得的最安全,最简单的选择。
  2. 存储日期对象,对其进行同步,并检查它是否相同。这是一个例子:
  3. class Myclass {
    
        //Static to make it possible to synchronize between instances of Myclass
        static Date lastDate;
    
        Date getUniqueTimeStamp() {
            synchronized (Myclass.lastDate) {
                Date newDate = new Date();
                if (newDate.getTime() <= Myclass.lastDate.getTime()) {
                    newDate.setTime(Myclass.lastDate.getTime()+1);
                }
                Myclass.lastDate.setTime(newDate.getTime());
                return newDate;
            }
        }
    }
    

答案 3 :(得分:0)

虽然不酷 - 您可以添加延迟然后创建数据。

class Myclass {

 Date getUniquetimeStam() {
   //in try catch
   Thread.sleep(100);
   //
   new Date();
  }

}