Java 通过生成类的多个实例使方法即使在调用方法时也是线程安全的

Java 通过生成类的多个实例使方法即使在调用方法时也是线程安全的,java,thread-safety,Java,Thread Safety,我想让线程保存方法返回唯一的当前时间戳。即使在同一时间调用该方法,我也希望获得唯一的当前日期时间。即使通过使MyClass的多个实例调用该方法,我希望它始终是线程安全的 class Myclass{ Date getUniquetimeStam(){ synchronized(Myclass.class){ //return date here } } 现在,如果我创建两个Myclass实例并同时调用getUniqueStam,是否可以返回uniue date ti

我想让线程保存方法返回唯一的当前时间戳。即使在同一时间调用该方法,我也希望获得唯一的当前日期时间。即使通过使MyClass的多个实例调用该方法,我希望它始终是线程安全的

class Myclass{

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

}

现在,如果我创建两个Myclass实例并同时调用getUniqueStam,是否可以返回uniue date time。

您是否可以将其更改为每次调用都返回一个新的date实例

class Myclass {

 Date getUniquetimeStam() {
   new Date();
  }

}

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

这里有两个选项:

  • 使用UUID而不是日期。阅读更多关于它的信息。UUID按规格保证每次生成时都是唯一的,因此它是您可以获得的最安全、最简单的选项
  • 存储日期对象,在其上同步,并检查其是否相同。下面是一个例子:
  • class-Myclass{
    //静态,使Myclass实例之间的同步成为可能
    静态日期lastDate;
    日期getUniqueTimeStamp(){
    已同步(Myclass.lastDate){
    Date newDate=新日期();
    
    如果(newDate.getTime(),您不能保证每次调用的时间都是唯一的。但是您可以手动增加它,如果它还没有改变:

    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();
        }
    }
    
    private AtomicLong lastTime=new AtomicLong();
    long getUniquetimeStam(){
    虽然(真的){//原子学的工作方式,但它们真的很快
    long now=System.currentTimeMillis();
    long last=lastTime.get();
    如果(上次<现在){
    if(lastTime.compareAndSet(last,now))
    现在就回来;
    }否则
    返回lastTime.incrementAndGet();
    }
    }
    
    但不酷-您可以添加延迟,然后创建数据

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

    我认为您考虑的是静态方法/属性不是线程安全的,但是如果您使用的是非静态方法,那么我看不出有多个类实例有什么关系。
    class Myclass {
    
     Date getUniquetimeStam() {
       //in try catch
       Thread.sleep(100);
       //
       new Date();
      }
    
    }