views:

89

answers:

4

I've been struggling with this for 7 days now. Your insights will be greatly appreciated.

Consider the framework code.

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() { }
}

and the code using it,

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 
 }
}

Right now, this program processes files in series. Any suggestion on how to make this program process files in parallel without touching the ProgrammerCode?

Aim: Each file should be processed independently in parallel using the implementation of the methods in ProgrammerCode without modifying it. The modification should be done somewhere in the framework code.

I really have no idea where to put the threading part here. My assumption is it should be in the file loop but I don't know if it's thread-safe since I'll be using the methods defined in the ProgrammerCode.

+1  A: 

One option would be to inject a ProgrammerCode provider rather than an actual ProgrammerCode. Then you could create one instance for each file, and execute those in parallel. Each instance of ProgrammerCode would only be used in a single thread.

Jon Skeet
A: 
abstract ProgramApp implements Interface {
 public void doProcess() { 
  for (File file : files) {
   new Thread(
      new Runnable() {
        public void run() {
             foo(file);
             bar(file);
        }
      }).start();
  }
 }
Moisei
+1  A: 

No matter what you do the implementer of ProgrammerCode can write bad code in general, and thread-unsafe code in particular. The best you can do is try to simplify the rules that the implementer must follow.

Hence Jon's suggestion of a simple rule, one ProgrammerCode per File makes a lot of sense. The implementer is then told that he has one instance of the ProgrammerCocde for each file, and that they have responsibility for any interaction between the instances.

djna
+1  A: 

My suggestion would to make file processing completely independent. This completely removes multithreading concern and allows to extend/implement Interface without caring about concurrency. You can use java.util.concurrent's ThreadPoolExecutor to execute file tasks in parallel.

The pseudocode would look like this:

main() {

File files; ThreadPoolExecutor pool;

for (File file: files) { pool.execute(new Runnable() { run() { Interface inter = (Interface) programmerCode; inter.doProcess(file); } }); }

Slava Imeshev
this works for me.
Joset