我如何构建一个多线程代码,以便在Java中更好地重用代码?

时间:2012-07-02 22:11:31

标签: java multithreading code-reuse code-structure

我正在用Java构建一个多线程项目,我有实体和DAO包来包装数据库表并操纵它们。我有包含Runnables的处理包。到目前为止我实现Runnables的方式是这样的:

Class Thread1 implements Runnable{
  Thread t;
   parameters
  ...

  public Thread1(){
    t = new Thread(this,"Thread1");
    ....
    t.start();
  }

  public int method1(){
  ...
  return x;
  }

  public double method2(){
  ...
  return y;
  }

  public void run(){
    // some processing using DAO methods
    ....
    method1();
    ... 
    method2();
    ...
  }

}

代码以这种方式工作,但我需要在run()方法中使用相同的处理作为Thread2类中处理的一部分。我构建代码的方式不允许重用代码。什么是更好的结构来解决这个问题?

4 个答案:

答案 0 :(得分:1)

你可以:

  1. 使Thread1Thread2扩展相同的抽象基类,并将共享逻辑移动到父级(继承)。
  2. 创建两个类实现并包含公共方法的公共接口,然后创建一个实现Runnable的单独类,并在那里实现run()(组合)。
  3. 你应该总是喜欢组合而不是继承,所以第二个选项通常更好,因为它还为你提供了在运行时改变行为的灵活性。

    例如: 首先创建一个共享接口

    public interface SharedTask {
        public void method1();
        public void method2();
    }
    

    让两个类实现它: public class Thread1 implements SharedTaskpublic class Thread2 implements SharedTask

    public class Worker implements Runnable {
    
        public Worker (SharedTask task) {
            this.task = task;
            ...
        }
    
        public void run() {
            task.method1();
            task.method2();
        }
    }
    

    代码中的其他地方: new Worker().start();

答案 1 :(得分:1)

您几乎不想自己创建和启动线程。只需实现Runnable(或者,如果您愿意,可以实现Callable)。然后将它们提交给ExecutorService,它为它运行的线程数提供了各种很酷的选项(如果你的需求发生变化,还有一个很好的中心位置可以在将来改变它),与CompletionService绑定,等...

答案 2 :(得分:0)

创建一个抽象类,在其run方法中使用您想要的代码实现Runnable - 然后将该类扩展多次,因为您需要在run方法中使用相同的功能。

答案 3 :(得分:0)

在深入了解多线程的细节之前:很可能所有DAO调用都将在一个数据库连接上运行,因此(几乎)在一个数据库线程上运行。 (特别是如果使用一些ORM框架,但是一个简单的数据源池会给你带来同样的效果)你绝对可以摆脱这个问题,但这意味着你必须使用两阶段提交的XA资源来保持ACID兼容。 是很大一部分工作,所以除非你准备好这样做,否则考虑appserver端的多线程细微差别是毫无意义的。