1

我正在用 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

4 回答 4

1

您可以:

  1. 创建Thread1Thread2扩展相同的抽象基类,并将共享逻辑移至父级(继承)。
  2. 创建两个类都实现并包含公共方法的公共接口,然后创建一个单独的实现类Runnable,并run()在那里实现(组合)。

您应该始终支持组合而不是继承,因此第二个选项通常更好,因为它还为您提供了在运行时更改行为的灵活性。

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

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();

于 2012-07-02T22:17:54.290 回答
1

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

于 2012-07-02T23:03:05.617 回答
0

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

于 2012-07-02T22:19:26.173 回答
0

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

于 2012-07-02T22:15:22.523 回答