【问题标题】:Calling static method by reflection is thread safe in java?通过反射调用静态方法在java中是线程安全的吗?
【发布时间】:2013-09-08 11:35:01
【问题描述】:

这段代码线程安全吗?

创建runnable并通过反射调用方法:

 public class A {
    public static void  someMethod (List<VO> voList){
        int endIndex=0;
        for (int firstIndex = 0; firstIndex < voList.size(); ) {
            endIndex = Math.min(firstIndex + threadSize, voList.size());
            Runner runner = null;
            try {
                runner = new Runner(voList.subList(firstIndex, endIndex),
                                    B.class.getMethod("createSomeString", D.class));
            } catch (NoSuchMethodException ex) {
                log.warn(ex.getMessage());
            }
            //start a thread
            runner.start();
        }

    }

    private static class Runner extends Thread {
        private Method method;
        private List<C> list;
        public Runner(Method method,List<C> clist) {
            this.method = method;
            this.list=clist;
        }
    }

    public void run() {
        for (C vo: list) {                
            String xml = (String) method.invoke(null,vo);
        }
    }
}

我想通过反射调用一个静态方法,这个代码块线程安全吗?

   public class B {
   public static String createSomeString(D a) throws Exception {
     return a.name;
   }
   }

而 D.class 是这样的普通旧 java 对象类:

   public class D implements Serializable{
   private String name;
   }

【问题讨论】:

  • 请更好地格式化您的代码以便我们阅读
  • 这是一个问题吗?二?线程安全取决于方法本身,而不是反射。
  • 通过反射进行方法调用与仅调用方法相比并不多或少是线程安全的。

标签: java multithreading reflection thread-safety


【解决方案1】:

如果您在方法中使用静态变量,或者任何其他需要线程安全的东西,synchronized 关键字是一种选择。

   public class B {
       public synchronized String createSomeString(A a) throws Exception {
         return a.name;
       }
   }

另一种选择是使用池大小为 1 的队列。 Google 提供了一个很好的示例项目,网址为:Running Code on a Thread Pool Thread

如果a.name 可以被多个线程访问,那么您需要同步它。

   public class B {
       public static String createSomeString(A a) throws Exception {
         String strName = "";
         synchronize (a.name) {
             strName = new String(a.name);
         }
         return strName;
       }
   }

【讨论】:

  • 在 b 类中我使用静态成员,但它是最终的。我应该同步 createSomeString 方法吗?
【解决方案2】:

您只在静态方法中执行读取操作,因此无论您的程序有多少并发,它都是线程安全的。如果同时涉及读写,那么你必须同步你的静态方法或代码块。

【讨论】:

    【解决方案3】:

    【讨论】:

    • 这有什么关系?示例中没有任何类或实例变量。
    猜你喜欢
    • 2010-11-08
    • 2018-10-23
    • 2016-07-16
    • 2018-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多