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_Rabbitmq_Messaging_Spring Rabbit - Fatal编程技术网

Java 弹簧连接工厂限位通道&;导致线程阻塞

Java 弹簧连接工厂限位通道&;导致线程阻塞,java,multithreading,rabbitmq,messaging,spring-rabbit,Java,Multithreading,Rabbitmq,Messaging,Spring Rabbit,我有一个简单的消息发布器,它以非常高的速率发布到rabbitmq(本地) ExecutorService threadPool = Executors.newFixedThreadPool(5, factory); for (int i = 1; i <= 1000000; i++) { int finalI = i; threadPool.submit(new Runnable() { @Override public void run(

我有一个简单的消息发布器,它以非常高的速率发布到rabbitmq(本地)

ExecutorService threadPool = Executors.newFixedThreadPool(5, factory);

for (int i = 1; i <= 1000000; i++) {
    int finalI = i;
    threadPool.submit(new Runnable() {
        @Override
        public void run() {
            messagePublisher.publishMessage("testExchange", "testRoutingKey1", message + String.valueOf(finalI));
        }
    });
}
执行此代码后,5个线程在单个连接上仅创建5个通道

编辑1 1). 为什么连接工厂在这里不提供超过5个线程,并且每个线程都关联线程? 这一部分现在很清楚,因为连接工厂不能提供比运行线程本身更多的通道(或连接)

接下来,所有线程立即开始在SocketFrameHandler中的监视器对象上被阻塞

“arpit-rmq-5”#1019优先级=5 os\U优先级=31 tid=0x00007fb90c5b8800 nid=0x83303正在等待监视器条目[0x0000700047bca000]
java.lang.Thread.State:阻塞(在对象监视器上) 位于com.rabbitmq.client.impl.SocketFrameHandler.writeFrame(SocketFrameHandler.java:170)

2) 。为什么这些线程会被阻塞?解决这些问题的解决方法是什么


注意:这将导致在流控制状态下移动我的兔子连接,对此我很好。我主要关心的是JVM中的线程阻塞。

您的问题不清楚-您只使用了5个线程
执行器为什么你希望工厂创建更多的线程?@GaryRussell如果这是幼稚的话,那很抱歉,但我正试图理解同样的道理。如果连接工厂总是返回与正在运行的线程数相等的通道集,那么为什么这些线程试图访问彼此的通道并进入阻塞状态。这些线程不应该执行它们的任务,将通道返回到缓存,并让其他线程在需要时重用通道吗?这正是发生的情况;每次发布后,通道将返回到缓存,并由下一个请求使用。由于您的发布速度很高,您可能只是因为网络带宽或代理问题而阻塞。由于您共享一个连接,因此每次写入都必须是离散的。考虑使用<代码> CasMeMod < /C> >代码>连接< /代码>,为每个发布者使用一个连接。或者这是因为在高度并行的环境中,多个线程从连接工厂获得相同的空闲(在那个时间点)通道?由于通过此连接的写套接字是同步的,因此某些线程被阻塞。示例线程转储(中间省略)
com.rabbitmq.client.impl.SocketFrameHandler.writeFrame(SocketFrameHandler.java:170)位于org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler.invoke(CachingConnectionFactory.java:955)
No;多个线程不可能同时获得同一个通道;然而,它们确实有着共同的联系。通道在其创建的连接上多路复用;为避免混合数据包,SocketFramewriter在套接字的
输出流上进行同步。一次只能有一个通道写入套接字。正如我所说,使用
cacheMode
连接可能会获得更好的性能,但如果限制因素是您的网络,则可能不会。您的问题不清楚-您只使用了5个线程
执行器。newFixedThreadPool(5,工厂)为什么你希望工厂创建更多的线程?@GaryRussell如果这是幼稚的话,那很抱歉,但我正试图理解同样的道理。如果连接工厂总是返回与正在运行的线程数相等的通道集,那么为什么这些线程试图访问彼此的通道并进入阻塞状态。这些线程不应该执行它们的任务,将通道返回到缓存,并让其他线程在需要时重用通道吗?这正是发生的情况;每次发布后,通道将返回到缓存,并由下一个请求使用。由于您的发布速度很高,您可能只是因为网络带宽或代理问题而阻塞。由于您共享一个连接,因此每次写入都必须是离散的。考虑使用<代码> CasMeMod < /C> >代码>连接< /代码>,为每个发布者使用一个连接。或者这是因为在高度并行的环境中,多个线程从连接工厂获得相同的空闲(在那个时间点)通道?由于通过此连接的写套接字是同步的,因此某些线程被阻塞。示例线程转储(中间省略)
com.rabbitmq.client.impl.SocketFrameHandler.writeFrame(SocketFrameHandler.java:170)位于org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler.invoke(CachingConnectionFactory.java:955)
No;多个线程不可能同时获得同一个通道;然而,它们确实有着共同的联系。通道在其创建的连接上多路复用;为避免混合数据包,SocketFramewriter在套接字的
输出流上进行同步。一次只能有一个通道写入套接字。正如我所说,使用
cacheMode
连接
可能会获得更好的性能,但如果限制因素是您的网络,则可能不会。
public class ChannelCachedMessagePublisher {

    private static CachingConnectionFactory CACHING_CONNECTION_FACTORY = new CachingConnectionFactory("localhost");
    private static RabbitTemplate RABBIT_TEMPLATE;

    private void init() {
        if (!INITIALIZED) {
            synchronized (ConnectionCachedMessagePublisher.class) {
                CACHING_CONNECTION_FACTORY.setCacheMode(CachingConnectionFactory.CacheMode.CHANNEL);
                CACHING_CONNECTION_FACTORY.setChannelCacheSize(100);
                CACHING_CONNECTION_FACTORY.setVirtualHost("testVHost");
                CACHING_CONNECTION_FACTORY.setConnectionNameStrategy(CACHING_CONNECTION_FACTORY -> "arpit-cached-connection");
                CACHING_CONNECTION_FACTORY.setPublisherConfirms(false);
                RABBIT_TEMPLATE = new RabbitTemplate(CACHING_CONNECTION_FACTORY);
            }
            INITIALIZED = true;
        }
    }

    public void publishMessage(String exchange, String routingKey, String message) {

        RABBIT_TEMPLATE.convertAndSend(exchange, routingKey, message, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                MessageProperties properties = message.getMessageProperties();
                properties.setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT);
                return new org.springframework.amqp.core.Message(message.getBody(),properties);
            }
        });
    }
}