2012-07-02 2 views
1

Я создаю многопоточный проект в Java, у меня есть сущности и пакеты DAO, чтобы обернуть таблицы базы данных и манипулировать ими. У меня есть пакет обработки, содержащий Runnables. Путь я реализовывал Runnables до сих пор, как это:Как я могу создать многопоточный код для лучшего повторного использования кода в java?

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 классе. То, как я структурировал свой код, не позволяет повторно использовать код. что было бы лучшей структурой для решения этой проблемы?

+1

Боковой комментарий: почему вы называете Runnable 'Thread1'? Почему бы не «Runnable1»? – assylias

+0

@assylias Я создаю поток внутри, поэтому – Sami

ответ

1

Вы можете либо:

  1. Сделать Thread1 и Thread2 продлить тот же абстрактный базовый класс, и переместить общую логику родителя (наследование).
  2. Создайте общий интерфейс, который реализует оба класса, и который содержит общие методы, затем создайте отдельный класс, который реализует 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();

+0

Я не получил второй вариант .. так что оба класса не были бы Runnables? и они создадут экземпляр отдельного класса Runnable? Если это так, что будет в методе 'run'? – Sami

+0

Я обновил свой ответ. – Jeshurun

+0

, но таким образом общие методы будут реализованы дважды в обоих классах (реализация одинакова для этих общих методов). Есть ли вообще, чтобы избежать их реализации в суперклассе, поскольку вы предложили избежать наследования. – Sami

0

Создайте абстрактный класс, который реализует Runnable с кодом, который вы хотите в его методе запуска, - затем расширяйте этот класс столько раз, сколько вам потребуется в той же функциональности в вашем методе запуска.

0

Прежде чем попасть в щегольской детали многопоточности: шансы, что все ваши DAO вызовы будут выполняться на одном соединении с базой данных, что (почти) на одной дб нити , (особенно если использовать некоторую структуру ORM, но простой пул источников данных даст вам такой же эффект). Вы можете определенно избавиться от этой проблемы, но это означает, что вам нужно использовать ресурсы XA с двухфазным фиксацией, чтобы оставаться совместимым с ACID. То, что большой объем работы, поэтому, если вы не готовы сделать это, бессмысленно думать о многопоточных нюансах на стороне сервера приложений.

1

Вы почти никогда не хотите создавать и запускать темы самостоятельно. Просто реализуйте Runnable (или, если хотите, Callable). Затем отправьте их в ExecutorService, в котором представлены всевозможные классные опции для того, сколько потоков оно выполняется (и хорошее центральное расположение, чтобы изменить это в будущем, если ваши потребности меняются), привязки к CompletionService и т. Д.

 Смежные вопросы

  • Нет связанных вопросов^_^