Java Sockets 并发线程太慢

标签 java multithreading sockets concurrency synchronized

我正在 Enterprise JavaBeans 3.1 中开发一个应用程序,我从 Socket 接收数据。该应用程序充当监听器,一旦接收到数据就会对其进行处理。该应用程序是单线程的,由于处理速度缓慢,该应用程序是使用线程实现的,现在是多线程应用程序。通过这样做,应用程序现在运行得更快。

但是,有两个线程,并且两个线程都访问数据库来插入和更新数据库。我面临并发问题,其中一个线程插入而其他线程更新导致问题。为了处理并发性,我添加了一个同步块(synchronized block)来锁定对象,以确保执行完整的 block 。通过这样做,该应用程序现在变得非常慢,就像使用单线程应用程序一样。插入和更新是通过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)

假设插入一条记录,而没有同步块(synchronized block)插入消息和sentDate。另一个线程将执行,导致找到并进一步更新该记录。问题是在初始插入和processedDate之后应该更新,然后另一个线程应该被执行。

processMessage() 通过 HTTPS 异步发送数据。

使用线程的原因之一是因为只有一份数据来到Java。因此,通过引入线程,完整的数据集就进入了 Java。

最佳答案

即使使用单线程,您也可以通过使用 JDBC 批处理并围绕批处理运行任何事务来获得更快的速度,而不是提交每个单独的插入/更新语句。

在多线程环境中,如果确保没有两个线程同时作用于同一数据库行,则可以避免并发问题。您可以使用行级锁来避免多个线程更新同一行。

根据您所提供的信息,我们无法为您提供更多信息。如果您提供有关您正在处理的数据的信息,您可能会得到更多想法。

关于Java Sockets 并发线程太慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24117284/

相关文章:

java - 抽象类中的 Selenium FindBy 注释

c - 在 Linux 中跟踪 pthreads?

Python SimpleXMLRPCServer : Socket Error , 连接被拒绝

java - spring-integration-ip 在连接(断开)时获取客户端的 ip

java - 无法使用 https 协议(protocol) (ssl) 访问网络服务

java - 在 jTable 中移动一行

java - Android自定义 View 布局问题

java - 一些 java 处理程序仅在结果可用时获取 url.openStream()

执行多线程数据库应用程序时出现 java.lang.NullPointerException

c - 在 c 中使用套接字时,FD_SET 和 FD_ISSET 背后的数据结构是什么?