代码之家  ›  专栏  ›  技术社区  ›  setzamora

如何保证重写方法的线程安全?

  •  1
  • setzamora  · 技术社区  · 14 年前

    我已经挣扎了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中定义的方法。

    4 回复  |  直到 14 年前
        1
  •  1
  •   Slava Imeshev    14 年前

    伪代码如下所示:

    主(){

    文件; 线程池执行器池;

    for(文件:文件){ pool.execute(新建Runnable(){ 运行(){ inter.doProcess(文件); } }); }

        2
  •  1
  •   Jon Skeet    14 年前

    一种选择是注入 ProgrammerCode 供应商 而不是真正的 程序代码 . 然后可以为每个文件创建一个实例,并并行执行这些实例。的每个实例 程序代码 只能在一个线程中使用。

        3
  •  1
  •   djna    14 年前

    不管你做什么,ProgrammerCode的实现者通常都会编写糟糕的代码,尤其是线程不安全的代码。您所能做的就是尽量简化实现者必须遵循的规则。

    因此Jon建议的一个简单规则,每个文件一个ProgrammerCode非常有意义。然后告诉实现者,每个文件有一个programmercode实例,他们负责实例之间的任何交互。

        4
  •  0
  •   Moisei    14 年前
    abstract ProgramApp implements Interface {
     public void doProcess() { 
      for (File file : files) {
       new Thread(
          new Runnable() {
            public void run() {
                 foo(file);
                 bar(file);
            }
          }).start();
      }
     }