如何知道JavaSE类或方法是否是线程安全的?
例如:如何知道JavaSE类或方法是否是线程安全的?,java,multithreading,thread-safety,Java,Multithreading,Thread Safety,例如: 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)
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));
}
});
}
static private DateFormat df=new SimpleDateFormat();
公共静态无效格式(最终日期){
对于(int i=0;i<10;i++)
新线程(newrunnable()){
公开募捐{
System.out.println(df.format(日期));
}
});
}
DateFormat
类不是一个同步类,但是如果我们只使用format方法,它不能更改整个类的状态
假设它声明为private,如何确保代码是线程安全的
修复此代码的最佳方法是什么
- 对于标准JavaSE类,了解该类是否线程安全的最佳方法是仔细阅读其文档。始终阅读类文档和方法文档。如果说它不是同步的,或者说它不是线程安全的,那么你就知道它不是线程安全的
- 因此,
类不是线程安全的。文件明确指出: 日期格式不同步。建议为每个线程创建单独的格式实例。如果多个线程同时访问一种格式,则必须在外部对其进行同步DateFormat
- 声明字段
不会使实现线程安全private
只是说外部类看不到该字段。让我们看看你的方法:private
for (int i=0;i<10;i++) new Thread(new Runnable(){ public void run(){ System.out.println(df.format(date)); } });
for(int i=0;i根据文档,该格式不是线程安全的 同步 日期格式未同步。建议为每个线程创建单独的格式实例。如果多个线程同时访问一种格式,则必须在外部同步 如何阅读这篇文章?如果你没有明确的保证某个方法是线程安全的(或者它被记录为不安全的),那么你就不能假设它是安全的 然而,如果您真的希望只使用可能不是完全状态的单一方法,那么您可以始终创建高并发环境,并测试数据完整性,包括同步和不同步 我也有类似的问题,关于密码和RSA。 这里的答案展示了一种测试java SE类的特定方法的方法。但是请注意,实现在任何时候都可能发生变化,并且通过根据实现细节而不是接口进行自己的实现,将来可能会导致一些不可预测的问题
我知道这很难相信,但是DateFormat.format()实际上修改了DateFormat的状态。例如,对于SimpleDataFormat:
其中,// Called from Format after creating a FieldDelegate private StringBuffer format(Date date, StringBuffer toAppendTo, FieldDelegate delegate) { // Convert input date to time field list calendar.setTime(date);
是日期格式的字段日历
因此,我只能建议您信任该文档。它可能知道您不知道的事情。通过仔细阅读文档,包括类文档和特定方法文档。DateFormat特别提到,如果我没有弄错的话,它不是线程安全的。好的,如果我们只使用该格式,它将被记录为未同步的类方法,它无法更改hole类的状态?如果一个类被记录为非线程安全的,如DateFormat,那么您就不再猜测哪个方法可能是线程安全的,或者可能不是线程安全的。您只是不在多个线程之间共享实例。顺便说一句,format()的事实更改或不更改状态与此无关:如果同时调用另一个方法,并且该方法更改了状态,则format()将破坏其不变量,并可能返回错误结果、引发异常或其他任何情况。读取方法的源代码并查看其工作方式非常有用,并且源代码可以在Internet上免费获得。但是,您不能依靠实现在所有版本中保持不变。如果您的程序不允许任何其他线程都可以接触对象,为什么您会担心线程安全?因此,即使该实例是my method格式的本地实例,并且我确信所有线程都只使用Format方法,我认为它是无状态的,但它仍然不是线程安全的?@NassimMOUALEK您不可能这么认为。这仍然不是线程安全的。如果文档中说是这样的话不是,也不是。多个线程访问实例=不是线程安全的。是的,但他们没有指定每个方法,他们将hole类记录为未同步,但我非常确定格式化日期应该是无状态的。在这种特殊情况下,我个人会使用同步块,因为
是ng无论如何都要慢一些,而且还涉及同步,因此同步的延迟可以忽略不计。此外,复制副本也要付出代价,这通常只有在线程多次使用实例时才是合理的。我的意思是,它有自己的同步块。System.out.println