【问题标题】:How to guarantee thread-safety for overridden methods?如何保证重写方法的线程安全?
【发布时间】:2010-08-16 11:58:58
【问题描述】:

我已经为此苦苦挣扎了 7 天。我们将不胜感激您的见解。

考虑框架代码。

final class Main {
 // assuming programmerCode was injected
 Interface inter = (Interface) programmerCode;
 inter.doProcess();
}

interface Interface {
 void doProcess();
}

abstract ProgramApp implements Interface {
 public void doProcess() { 
  for (File file : files) {
   foo(file);
   bar(file);
  }
 }

 public abstract void foo(File file);
 public abstract void bar(File file);
}

abstract Program extends ProgramApp {
 public final void doProcess() { }
}

以及使用它的代码,

class ProgrammerCode extends Program {

 File file;
 String a1;
 String a2;

 public void foo(File file) {
  // read file per line store in a1
 }

 public void bar(File file) {
  // read file per line and append somestring and store in a2 
 }
}

目前,该程序按顺序处理文件。关于如何在不触及 ProgrammerCode 的情况下使该程序并行处理文件的任何建议?

目标:每个文件都应该使用 ProgrammerCode 中的方法实现独立地并行处理,而不需要修改它。修改应该在框架代码的某处进行。

我真的不知道把线程部分放在哪里。我的假设是它应该在文件循环中,但我不知道它是否是线程安全的,因为我将使用 ProgrammerCode 中定义的方法。

【问题讨论】:

    标签: java multithreading thread-safety


    【解决方案1】:

    我的建议是让文件处理完全独立。这完全消除了多线程问题,并允许在不关心并发的情况下扩展/实现接口。您可以使用 java.util.concurrent 的 ThreadPoolExecutor 来并行执行文件任务。

    伪代码如下所示:

    主() {

    文件文件; ThreadPoolExecutor 池;

    for(文件文件:文件){ pool.execute(新可运行(){ 跑() { 接口inter =(接口)programmerCode; inter.doProcess(文件); } }); }

    【讨论】:

      【解决方案2】:

      一种选择是注入ProgrammerCode provider 而不是实际的ProgrammerCode。然后,您可以为每个文件创建一个实例,并并行执行这些实例。 ProgrammerCode 的每个实例只能在单个线程中使用。

      【讨论】:

        【解决方案3】:

        无论您做什么,ProgrammerCode 的实现者通常都会编写糟糕的代码,尤其是线程不安全的代码。您能做的最好的事情就是尽量简化实施者必须遵守的规则。

        因此,Jon 提出了一个简单规则的建议,即每个文件一个 ProgrammerCode 很有意义。然后告诉实现者,他对每个文件都有一个 ProgrammerCocde 实例,并且他们负责实例之间的任何交互。

        【讨论】:

          【解决方案4】:
          abstract ProgramApp implements Interface {
           public void doProcess() { 
            for (File file : files) {
             new Thread(
                new Runnable() {
                  public void run() {
                       foo(file);
                       bar(file);
                  }
                }).start();
            }
           }
          

          【讨论】:

            猜你喜欢
            • 2018-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-12-04
            • 1970-01-01
            • 2013-03-01
            相关资源
            最近更新 更多