ThreadLocal 变量没有改变

ThreadLocal variable is not changed

我有下面给出的代码,它使用 ThreadLocal 为每个线程存储一个单独的 SimpleDateFormat 副本。我的初始模式是 MM/dd/yyyy.

class PerThreadLocalVariables {
   public static final ThreadLocal<SimpleDateFormat> THREAD_LOCAL_FORMATTER = ThreadLocal
        .withInitial(() -> new SimpleDateFormat("MM/dd/yyyy"));
}

我有以下任务 'TransactionService',它使用 ThreadLocal 实例来记录 txn 的开始日期。这个 class 还有一个方法可以为特定任务更改 SimpleDateFormat -

class TransactionService implements Runnable {

  @Override
  public void run()
  {
    System.out.println(Thread.currentThread().getName() + ": startDate= "
            + PerThreadLocalVariables.THREAD_LOCAL_FORMATTER.get().format(new Date()));

    try
    {
        Thread.sleep(10000);
        System.out.println("After some time ... " + Thread.currentThread().getName() + ": date pattern= "
                + PerThreadLocalVariables.THREAD_LOCAL_FORMATTER.get().toPattern());

    }
    catch( InterruptedException e )
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

  }

  public void changeFormatterToYYYMMDD()
  {
    // Changing the thread local variable will not affect variable of other thread.
    PerThreadLocalVariables.THREAD_LOCAL_FORMATTER.set(new SimpleDateFormat("yyyy/MM/dd"));
  }
}

现在在主要方法中我创建了三个线程并启动它们,对于第一个线程(thread-1)我正在将 SimpleDateFormat 模式更改为 yyyy/MM/dd。因此,根据 ThreadLocal 概念,更改这不应影响其他两个线程(线程 2 和线程 3)使用的模式。但问题是它甚至没有改变线程 1 的模式。我仍然看到初始模式,即 MM/dd/yyyy。我不确定我在这里做错了什么-

public class ThreadLocalDemo {

  public static void main( String[] args ) throws InterruptedException
  {
    TransactionService txn1 = new TransactionService();
    new Thread(txn1, "thread-1").start();

    Thread.sleep(2000);
    new Thread(new TransactionService(), "thread-2").start();
    Thread.sleep(5000);
    new Thread(new TransactionService(), "thread-3").start();

    txn1.changeFormatterToYYYMMDD(); // this will not affect thread-2 and thread-3's simpleDateFormat pattern
    System.out.println("Changed SimpleDateFormat pattern to yyyy/MM/dd for thread-1");

  }
}

输出 -(您仍然可以看到线程 1 的模式是相同的,即 MM/dd/yyyy,它应该根据代码更改为 yyyy/MM/dd)

thread-1: startDate= 11/25/2019
thread-2: startDate= 11/25/2019
Changed SimpleDateFormat pattern to yyyy/MM/dd for thread-1
thread-3: startDate= 11/25/2019
After some time ... thread-1: date pattern= MM/dd/yyyy
After some time ... thread-2: date pattern= MM/dd/yyyy
After some time ... thread-3: date pattern= MM/dd/yyyy

For first thread (thread-1) I am changing the SimpleDateFormat pattern to yyyy/MM/dd.

不,你不是。

您正在 main 线程中调用 txn1.changeFormatterToYYYMMDD()。那不是 thread-1。您总共有 四个 个线程:执行 main 方法的线程,以及您单独创建的三个线程。

所以您要更改的唯一模式是从未记录的模式。