“Calendars” and “DateFormats” should not be static
级别:bug, multi-threading
Not all classes in the standard Java library were written to be thread-safe. Using them in a multi-threaded manner is highly likely to cause data problems or exceptions at runtime.
This rule raises an issue when an instance of Calendar, DateFormat, javax.xml.xpath.XPath, or javax.xml.validation.SchemaFactory is marked static.
Noncompliant Code Example
public class MyClass {
static private SimpleDateFormat format = new SimpleDateFormat("HH-mm-ss"); // Noncompliant
static private Calendar calendar = Calendar.getInstance(); // Noncompliant
Compliant Solution
public class MyClass {
private SimpleDateFormat format = new SimpleDateFormat("HH-mm-ss");
private Calendar calendar = Calendar.getInstance();
不要在多线程环境下将这两个类成员声明为static
,Calendars
和DateFormats
并不是线程安全的类型,意味着在多线程环境下可能由于其他线程改变了这两个静态成员对象导致当前线程使用时无法得到理想的结果。
为什么不能是static
类型呢?
线程安全问题发生的两个必要条件:1. 存在共享变量。2. 存在某个线程对共享变量存在写操作
static
类型意味着该变量属于当前类,很容易在使用时改变当前类对象,从而引起潜在的线程安全问题。
其实,就算不声明成static
也不意味着线程安全问题完全得到解决,当多个线程同时操作该类型的实例时,仍然可能导致线程安全问题,只是这种几率比较小(多个线程同时操作某个包含SimpleDateFormat
类型的实例)。
如何解决这个问题?
从线程安全问题的必要条件入手。
可以把成员声明为final
,使其不可被改写。
或不声明为static
减少线程安全问题发生的几率。