Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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_Concurrency_Consumer_Synchronisation - Fatal编程技术网

Java 一个生产者多个消费者的表现

Java 一个生产者多个消费者的表现,java,multithreading,concurrency,consumer,synchronisation,Java,Multithreading,Concurrency,Consumer,Synchronisation,我的Java程序具有客户机-服务器体系结构。在客户端,我创建了一条消息,并使用10000个线程将其发送到服务器,就像10000个客户端同时发送一条消息一样。在服务器类端,我有一个固定大小的队列,每个消息都必须先放到这个队列中。然后使用多个通道或多个客户端同时读取消息。若一个通道或消费者读取了一条消息,则必须从队列中删除该消息。 但是多个频道不能给我比一个频道更高的性能。我认为线程的同步有问题。如何优化我的计划?这是我的节目 İn客户端我有一个可运行的类,显示用于发送消息的类的重要部分 publi

我的Java程序具有客户机-服务器体系结构。在客户端,我创建了一条消息,并使用10000个线程将其发送到服务器,就像10000个客户端同时发送一条消息一样。在服务器类端,我有一个固定大小的队列,每个消息都必须先放到这个队列中。然后使用多个通道或多个客户端同时读取消息。若一个通道或消费者读取了一条消息,则必须从队列中删除该消息。 但是多个频道不能给我比一个频道更高的性能。我认为线程的同步有问题。如何优化我的计划?这是我的节目

İn客户端我有一个可运行的类,显示用于发送消息的类的重要部分

public void run() 
{  
   pw.println(message+numberofmessage);
}
在主客户端类中

ExecutorService pool = Executors.newFixedThreadPool(axinsayi);
          for(int i=1;i<=countofUser;i++)
          {
            pool.execute(new SendMessagetoServer(pw,message,i));
          }
           pool.shutdownNow(); 
并读取此缓冲区,并使用

public void run() 
{    
    while (true) 
    {
        synchronized (queue) 
        {
            while (queue.isEmpty()) 
            {
                try {queue.wait();} 
                catch (InterruptedException ex) {}
            }
            line=(String)queue.remove();

        // ORACLE DB İnsert part    
            if(conn==null)
           { 
             try { DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
                   conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl",          "HR", "Ilkinpassword");} 
             catch (SQLException ex) {System.out.println("Connection not created");}
           }
           try {String sql = "insert into hr.info values('"+line+"')";
                ps = conn.prepareStatement(sql);
                ps.executeUpdate();
                System.out.println(line + " inserted to DB");} 
            catch (SQLException ex) {System.out.println(line+"cant inserted to DB");}
            try {ps.close();} 
            catch (SQLException ex) {}
            queue.notifyAll();
        }
    }
}
我创建的多个频道

public void run() 
{ 
    for(int i=1;i<=counntofChannel;i++)
    {
      pool.execute(new WriteFromQueuetoDB(queue));
    }
     pool.shutdownNow();
}

synchronizedqueue块之外可以进行的事情很少,因为它们是独立的,因此可以并行进行

 try {line=input.readLine();} 
            catch (IOException ex) {}
            System.out.println("Entered to buffer : " + line);
而且

// ORACLE DB İnsert part    
    if(conn==null)
   { 
     try { DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
           ...
    queue.notifyAll();

基本上,您需要减少同步{}块中出现的代码量,正如@Debasish所指出的,您与数据库和文件系统的交互阻碍了您释放队列上的锁,并阻止其他线程与队列交互。从我所看到的,您只需要对队列进行读写同步,但所有其他工作都应该在任何同步块之外

我建议您尝试实现同步,这样您就不必自己实现同步。让JavaAPI为您更有效地完成这项工作


见此了解想法

您不能删除已投票/接受答案的问题。同时,试图删除您的问题。
 try {line=input.readLine();} 
            catch (IOException ex) {}
            System.out.println("Entered to buffer : " + line);
// ORACLE DB İnsert part    
    if(conn==null)
   { 
     try { DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
           ...
    queue.notifyAll();