如何知道Java SE类或方法是否是线程安全的? [英] How to know if a Java SE class or method is thread safe?
问题描述
例如:
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
类被记录为不是同步类,但是如果我们仅使用format方法,那么它不能更改整个类的状态吗?
The DateFormat
class is documented as not a synchronized class, but if we use just the format method, it can't change the status of the whole class?
假设它已声明为私有,那么如何确保代码是线程安全的?
Suppose it's declared private, how can one be sure that the code is thread safe?
修复此代码的最佳方法是什么?:
What is the best way to fix this code?:
-
为每个线程使用不同的实例.
Using a different instance for every thread.
使用同步块.
推荐答案
- 对于标准Java SE类,了解该类是否为线程安全的最佳方法是仔细阅读其文档.始终阅读类文档和方法文档.如果有人说它不同步或不是线程安全的,那您就知道它不是线程安全的.
-
因此,
DateFormat
类不是线程安全的.该文档特别指出:- For a standard Java SE class, the best way to know whether or not the class is thread-safe is to carefully read its documentation. Always read both the class documentation and the method documentation. If either say it's not synchronized or not thread-safe, you know it's not thread-safe.
Therefore, the
DateFormat
class is not thread safe. The documentation specifically says:日期格式不同步.建议为每个线程创建单独的格式实例.如果多个线程同时访问一种格式,则必须在外部进行同步.
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.
-
声明字段
private
不会不是使您的实现具有线程安全性.private
仅表示外部类看不到该字段.让我们看看您的方法: Declaring a field
private
does not make your implementation thread-safe.private
merely says that outside classes can't see that field. Let's look at your method:for (int i=0;i<10;i++) new Thread(new Runnable(){ public void run(){ System.out.println(df.format(date)); } });
您创建的
Runnable
对象是匿名类.匿名类是 inner 类,可以访问其周围类的私有字段.如果不是这样,则您的程序将无法编译-他们无法访问df
字段.The
Runnable
objects that you create are anonymous classes. Anonymous classes are inner classes, which have access to private fields of their surrounding class. If it wasn't so, your program would not compile - they could not access thedf
field.但是他们可以.因此,实际上您有10个线程都在访问由
df
引用的一个DateFormat
对象.由于我们已经知道DateFormat
是不是线程安全的,因此您的程序不是线程安全的.But they can. So in fact you are having 10 threads that are all accessing your one
DateFormat
object, referred to bydf
. Since we already know thatDateFormat
is not thread-safe, your program is not thread-safe.这篇关于如何知道Java SE类或方法是否是线程安全的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!