Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何知道JavaSE类或方法是否是线程安全的?_Java_Multithreading_Thread Safety - Fatal编程技术网

如何知道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类记录为未同步,但我非常确定格式化日期应该是无状态的。在这种特殊情况下,我个人会使用同步块,因为
      System.out.println
      是ng无论如何都要慢一些,而且还涉及同步,因此同步的延迟可以忽略不计。此外,复制副本也要付出代价,这通常只有在线程多次使用实例时才是合理的。我的意思是,它有自己的同步块。