2013-10-13 3 views
0

Мне нужно прочитать данные из таблицы и выполнить некоторую работу над каждой строкой и пометить строку как обновленную. Я не хочу снова читать обновленную строку. Вот что я планирую делать с ExecutorService. Это верно ?Попытка реализовать рабочий поток

Спасибо.

public class ScheduledDBPoll 
{ 
    public static void main(String args[]) 
    { 
     ExecutorService service = Executors.newFixedThreadPool(10); 
     /* Connect to database. */ 
     while (true) 
     { 
     /* Issue a select statment for un-updated rows. */ 
      /* Get the primary key. */ 

      service.submit(new Task(primaryKey));  /* Pass the primary key*/ 
      try 
      { 
       Thread.sleep(3000);  /* Sleep for 3 seconds. */ 
      } 
      catch (InterruptedException ex) 
      { 
       Logger.getLogger(ScheduledDBPoll.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 
     /* Close the connection here. */ 
    } 
} 

final class Task implements Runnable 
{ 
    private int taskId; 

    public Task(int primayKey) 
    { 
     this.taskId = primayKey; 
    } 

    @Override 
    public void run() 
    { 
     try 
     { 
      /* Connect to database. */ 
      /* Select the passed primary key row. */ 
      /* Do some work, mark the row as updated. */ 
      /* Close the connection here. */    
     } 
     catch (InterruptedException ex) 
     { 
      Logger.getLogger(Task.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

Я использую базу данных Firebird, Firebird является только потокобезопасной на уровне соединения. Поэтому я стараюсь избегать двух запросов в разных потоках, работающих против одного и того же соединения. Я также забыл упомянуть, что вышеупомянутый фрагмент кода будет запущен как служба Windows, поэтому он всегда будет искать недавно вставленные записи.

+3

запустить его и посмотреть. –

+0

, когда я вижу 'while (true) {...}', тогда я знаю, что что-то не так – alex

+1

Этот код не кажется полным .. Вы собираетесь запустить это навсегда? Нет условия для завершения 'while (true) {...}' .. и откуда инициализируется 'primaryKey'? – bram

ответ

0

Во-первых, проблема терминологии, которая может быть важной: этот код не реализует «a» рабочий поток; он пытается одновременно выполнять одновременный доступ к базе данных до 10 потоков.

Так что если вы действительно сделали, на самом деле нужно только один рабочий поток, ваш фиксированный пул потоков должен быть размером 1, а не 10. Но тогда вам могут не понадобиться отдельные задачи, у вас может быть одна задача для всего и все становится проще.

Я не знаю, почему вы ждёте 3 секунды (на самом деле это одна секунда, несмотря на то, что говорит ваш комментарий), что кажется бессмысленным.

Кроме этого, кажется правильным.

1

Я бы использовал службу ScheduledExecutorService и не имел потока, который отправляет задание каждые три секунды. Я также поддерживал бы соединение открытым, поскольку создание соединения с базой данных происходит очень медленно.

Так что я бы реализовать это больше похоже

ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(); 
service.scheduleAtFixedRate(new Task(), 1, 1, TimeUnit.SECONDS); 


final class Task implements Runnable { 
    private Connection connection; 
    private int taskId; 

    @Override 
    public void run() { 
     try { 
      if (!connectionIsOkay()) { 
       connectToDatabase(); 
       taskId = selectUnUpdatedRow(); 
      } 
      selectRowsToUpdate(); 
      processRowsToUpdate(); 
      markAsUpdated(); 

     } catch (Exception ex) { 
      Logger.getLogger(Task.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
    // TODO find a more elegant way to close the connection when finished. 
    public void finalise() { 
     closeConnection(); 
    } 
} 
+0

Обновлено; взгляни, пожалуйста! – Sudheer

+0

@Sudheer Я не вижу ничего, что могло бы изменить мой ответ, кроме того, что вам не нужен метод 'finalize()' –

+0

Я использую базу данных Firebird, Firebird только потокобезопасна на уровне соединения. Поэтому я стараюсь избегать двух запросов в разных потоках, работающих против одного и того же соединения. Я также забыл упомянуть в своем первом сообщении, что вышеупомянутый фрагмент кода будет запущен как служба Windows, поэтому он всегда будет искать недавно вставленные записи, поэтому в течение 3 секунд после каждого выбора. – Sudheer

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