2014-06-09 4 views
1

Я разрабатываю приложение в Enterprise JavaBeans 3.1 и получаю данные от Socket. Это приложение действует как слушатель, и после получения данных он обрабатывается. Это приложение было однопоточным и из-за его медленной обработки, приложение реализовано с помощью Threads, который теперь является многопоточным приложением. Таким образом, приложение теперь работает намного быстрее.Java Sockets Concurrency Threads To To Slow

Однако есть два потока, и оба потока обращаются к базе данных для вставки и обновления базы данных. Я сталкиваюсь с проблемой параллелизма, когда одна вставка потока и другие обновления вызывают проблемы. Чтобы справиться с параллелизмом, я добавил синхронизированный блок, чтобы заблокировать объект, убедившись, что выполняется полный блок. Выполнение этого приложения сейчас очень медленное, как это было с однопоточным приложением. Вставка и обновление выполняются через JDBC.

Есть ли что-то еще, что можно сделать так, чтобы оно обрабатывалось и обрабатывалось очень быстро, не замедляя работу приложения. Ниже приведен пример код:

@Startup 
@Singleton 
public class Listener { 

    private ServerSocket serverSocket; 
    private Socket socket; 
    private Object object; 
    private InetAddress server; 
    @Resource 
    private ScheduledExecutorService executor; 

    @PostConstruct 
    public void init() { 
      object = new Object(); 
      serverSocket = new ServerSocket("somePortNumber"); 
      Runnable runnable = new Runnable() { 
       public void run() { 
       checkDatabase(); 
       if(!isServerActive()) { 
        // send e-mail 
        listen(); 
       } 
       else { 
        listen(); 
       } 
       } 
      }; 
      executor.scheduleAtFixedRate(runnable, 0, 0, TimeUnit.SECONDS); 
    } 

    public void listen() { 
      if(socket == null) { 
       socket = serverSocket.accept(); 
      } 
      else if(socket.isClosed()) { 
       socket = serverSocket.accept(); 
      } 
      startThread(socket); 
    } 

    public void startThread(Socket socket) { 
      Runnable runnable = new Runnable() { 
       public void run() { 
        processMessage(socket); 
       } 
      }; 
      new Thread(runnable).start(); 
    } 

    public void processMessage(Socket socket) { 
      synchronized(object) { 
       // build data from Socket 
       // insert into database message, sentDate 
       // do other things 
       // update processDate 
     } 
    } 

    public void checkDatabase() { 
     synchronized(object) { 
      // get data and further update 
     } 
    } 

    public boolean isServerActive() { 
     boolean isActive = true; 
     if(server == null) { 
      sever = InetAddress.getByName("serverName"); 
     } 
     if(!server.isNotReachable(5000)) { 
      isActive = false; 
      if(socket != null) { 
      socket.close(); 
      } 
     } 
     return isActive; 
    } 
} 

РЕДАКТИРОВАТЬ:

Table name: Audit 

Message: VARCHAR NOT NULL 
SentDate: DATE NOT NULL 
ProcessedDate: DATE 
AnotherDate: DATE 

Query: INSERT INTO AUDIT (message, sentDate, processedDate, receivedDate) VALUES (?, java.sql.Timestamp, null, null) 

Предполагая, что запись вставляется без синхронизированного блока вставки сообщения и sentDate. Другой поток будет выполнен, и эта запись будет найдена и обновлена. Проблема в том, что после того, как начальная вставка и обработанная дата должны быть обновлены, а затем должен быть выполнен другой поток.

ПроцессMessage() передает данные через HTTPS асинхронно.

Одна из причин использования Threads заключалась в том, что на Java появилась только одна часть данных. Таким образом, вводя потоки, полный набор данных поступает на Java.

+0

Таким образом, вашей проблемой параллелизма была база данных, а не потоковая передача. Я предлагаю вам опубликовать данные о таблице, вставке и запросе. – EJP

+0

См. Изменение выше. – user3189663

ответ

1

Даже с одной нитью вы можете получить намного лучшую скорость, используя JDBC-пакетную обработку и выполнение любых транзакций вокруг партии вместо того, чтобы выполнять каждую отдельную инструкцию вставки/обновления.

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

Невозможно предоставить вам дополнительные данные с информацией, которую вы указали. Вы можете получить больше идей, если вы предоставите информацию о данных, которые вы обрабатываете.

+0

+1 для пакетных вставок/обновлений –

+0

Могут ли блокировки уровня строк реализовать на Java через JDBC? Данные - это входящие сообщения. Я не могу дать подробностей сообщения, но есть записи клиентов, поступающие в определенном формате. Проблема в том, что я не могу использовать JDBC-пакет, потому что приложение является ayshcronronous. Это означает, что при получении данных он обрабатывается и отправляется через HTTPS с помощью aysnchrnonous. – user3189663

+1

@ user3189663 Вы были заблокированы от Google? Вторая ссылка на «JDBC row lock» дает довольно хорошее руководство. – Ordous

0

Приложение ведёт себя как однопоточное, потому что методы checkDatabase processMessage & имеют синхронизированный блок в одном объекте класса, потоки, которые в настоящее время прослушиваются, будут удерживать блокировку, а другие потоки должны будут ждать, пока сообщение будет обработано, что будет чтобы приложение замедлялось. вместо того, чтобы синхронизировать в двух отдельных блоках, создавайте отдельные потоки вне класса, который проверяет это условие и пытается вызвать его отдельно по условию, или вы можете попробовать с wait() и notifyAll в ваших синхронизированных блоках.

+1

. Я точно не понимаю, когда вы имеете в виду. Не могли бы вы привести пример кода, чтобы показать это? – user3189663

+0

Не могли бы вы рассказать мне, как это условие задано? –

+0

См. Править выше. Я добавил еще несколько кодов. Код показывает установленное условие. – user3189663