static private DateFormat df = new SimpleDateFormat(); public static void format(final Date date){ for (int i=0;i<10;i++) new Thread(new Runnable(){ public void run(){ System.out.println(df.format(date)); } }); }
它记录的DateFormat类不是同步类,但如果我们只使用格式Method,它不能改变孔类的法定?
假设它被声明为私有,如何确保此代码是线程安全的?
1_ Using a different instance for every Thread. 2_ Using a synchronized block.
解决方法
>因此,DateFormat类不是线程安全的.文档具体说:
Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently,it must be synchronized externally.
>声明字段私有不会使您的实现线程安全.私人只是说外面的课不能看到那个领域.我们来看看你的方法:
for (int i=0;i<10;i++) new Thread(new Runnable(){ public void run(){ System.out.println(df.format(date)); } });
您创建的Runnable对象是匿名类.匿名类是内部类,可以访问其周围类的私有字段.如果不是这样,你的程序将无法编译 – 他们无法访问df字段.
但他们可以.所以实际上你有10个线程都访问你的一个DateFormat对象,由df引用.由于我们已经知道DateFormat不是线程安全的,因此您的程序不是线程安全的.>此外,如果两个外部线程引用了您的对象(我的意思是在其中包含df的对象.您没有给出类声明,因此我不知道它的名称是什么).它们引用了同一个类的实例.如果它们都同时调用format,则两者都将使用相同的私有df运行DateFormat.format.因此,这不是线程安全的.>为了线程安全,您需要在对象上进行同步或使用其他类型的锁(对于访问它的所有可能线程都有一个锁),这正是文档所说的.>另一种方法是拥有一个完全本地的对象,只有一个线程可见.不是字段 – 一个局部变量,可以访问唯一创建的DateFormat实例(因此每次调用方法时都有一个新副本).但要注意匿名课程!在您的示例中,即使df是format方法的本地字段,它仍然不是线程安全的,因为所有线程都将访问同一副本.