我正在用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
类中处理的一部分。我构建代码的方式不允许重用代码。什么是更好的结构来解决这个问题?
答案 0 :(得分:1)
你可以:
Thread1
和Thread2
扩展相同的抽象基类,并将共享逻辑移动到父级(继承)。Runnable
的单独类,并在那里实现run()
(组合)。你应该总是喜欢组合而不是继承,所以第二个选项通常更好,因为它还为你提供了在运行时改变行为的灵活性。
例如: 首先创建一个共享接口
public interface SharedTask {
public void method1();
public void method2();
}
让两个类实现它:
public class Thread1 implements SharedTask
和public 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端的多线程细微差别是毫无意义的。