Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java套接字并发线程速度太慢_Java_Multithreading_Sockets_Concurrency_Synchronized - Fatal编程技术网

Java套接字并发线程速度太慢

Java套接字并发线程速度太慢,java,multithreading,sockets,concurrency,synchronized,Java,Multithreading,Sockets,Concurrency,Synchronized,我正在EnterpriseJavaBeans 3.1中开发一个应用程序,我从套接字接收数据。此应用程序充当侦听器,一旦接收到数据,就会对其进行处理。这个应用程序是单线程的,由于它处理速度慢,所以应用程序是使用线程实现的,而线程现在是多线程应用程序。通过这样做,应用程序现在运行得更快 但是,有两个线程,两个线程都访问数据库以插入和更新数据库。我面临一个并发问题,其中一个线程插入,另一个线程更新导致问题。为了处理并发性,我添加了一个synchronized块来锁定一个对象,以确保执行完整的块。通过这

我正在EnterpriseJavaBeans 3.1中开发一个应用程序,我从套接字接收数据。此应用程序充当侦听器,一旦接收到数据,就会对其进行处理。这个应用程序是单线程的,由于它处理速度慢,所以应用程序是使用线程实现的,而线程现在是多线程应用程序。通过这样做,应用程序现在运行得更快

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

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

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


使用线程的原因之一是因为只有一段数据进入Java。因此,通过引入线程,Java可以获得完整的数据集。

即使使用单线程,也可以通过使用JDBC批处理和在批处理中运行任何事务,而不是提交每个insert/update语句,获得更快的速度

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


您所提供的信息不可能为您提供更多的输入。如果提供有关正在处理的数据的信息,您可能会有更多的想法。

应用程序表现为单线程,因为processMessage和checkDatabase方法在同一类对象上具有同步块,当前正在侦听的线程将持有锁,其他线程将不得不等待消息被处理,这将导致应用程序速度减慢。不要将synchronized放在两个单独的块中,而是在检查此条件的类之外创建单独的线程,然后尝试根据条件单独调用,或者您也可以尝试在同步块中使用wait()和notifyAll。

因此,并发性问题是数据库,而不是线程。我建议您发布表、插入和查询的详细信息。请参见上面的编辑。行级锁可以通过JDBC在Java中实现吗?数据正在发送消息。我真的不能给出消息的任何细节,但是有一些客户记录以某种定义的格式出现。问题是我不能使用JDBC批处理,因为应用程序是Ayshcronous的。这意味着当接收到数据时,它会以一种不正当的方式通过HTTPS进行处理和发送。@user3189663您被禁止进入谷歌了吗?关于“JDBC行锁”的第二个链接提供了一个很好的指南。很抱歉,我不能提供更多的可用信息。第二个链接是什么意思。你能附上这个链接吗?我得到的第二个链接来自谷歌。如果你能发布这个链接,那会很有帮助。我不太明白你的意思。你能给出一个示例代码来说明这一点吗?你能告诉我条件是如何设置的吗?请参见上面的编辑。我添加了更多的代码。该代码显示设置的条件。
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)