Java - 连接到localhost的速度很慢

时间:2016-10-24 04:41:51

标签: java network-programming netty

我最近更换了PC,并注意到有一段代码片段比平常花了很长时间。据我所知,代码基本上是引导Netty(它在第三方库中)。我已抽象出代码来证明这一点。它需要大约3.6秒(对于一个线程,或对于5个线程大约15秒)

import io.netty.channel.nio.NioEventLoopGroup;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

public class Foo {

    public static void main(String[] args) {
        final long stsart = System.currentTimeMillis();
        NioEventLoopGroup workers = new NioEventLoopGroup(1, new NamedThreadFactory("Worker-", true));
        final long finish = System.currentTimeMillis();
        System.out.println(finish - stsart);
    }


    public static class NamedThreadFactory implements ThreadFactory {
        private final String prefix;
        private final boolean daemon;
        private final AtomicInteger threadNumber = new AtomicInteger(0);

        public NamedThreadFactory(String prefix, boolean daemon) {
            this.prefix = prefix;
            this.daemon = daemon;
        }

        public Thread newThread(Runnable r) {
            Thread t = new Thread(r, this.prefix + this.threadNumber.incrementAndGet());
            t.setDaemon(daemon);
            return t;
        }
    }
}

我做了一个线程转储,这是主线程的结果:

"main" #1 prio=5 os_prio=0 tid=0x00000000024f7000 nid=0x11efc runnable [0x000000000273d000]
   java.lang.Thread.State: RUNNABLE
    at sun.nio.ch.Net.connect0(Native Method)
    at sun.nio.ch.Net.connect(Net.java:454)
    at sun.nio.ch.Net.connect(Net.java:446)
    at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:648)
    - locked <0x0000000717ef20d0> (a java.lang.Object)
    - locked <0x0000000717ef20f0> (a java.lang.Object)
    - locked <0x0000000717ef20e0> (a java.lang.Object)
    at java.nio.channels.SocketChannel.open(SocketChannel.java:189)
    at sun.nio.ch.PipeImpl$Initializer$LoopbackConnector.run(PipeImpl.java:127)
    at sun.nio.ch.PipeImpl$Initializer.run(PipeImpl.java:76)
    at sun.nio.ch.PipeImpl$Initializer.run(PipeImpl.java:61)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.nio.ch.PipeImpl.<init>(PipeImpl.java:171)
    at sun.nio.ch.SelectorProviderImpl.openPipe(SelectorProviderImpl.java:50)
    at java.nio.channels.Pipe.open(Pipe.java:155)
    at sun.nio.ch.WindowsSelectorImpl.<init>(WindowsSelectorImpl.java:127)
    at sun.nio.ch.WindowsSelectorProvider.openSelector(WindowsSelectorProvider.java:44)
    at io.netty.channel.nio.NioEventLoop.openSelector(NioEventLoop.java:126)
    at io.netty.channel.nio.NioEventLoop.<init>(NioEventLoop.java:120)
    at io.netty.channel.nio.NioEventLoopGroup.newChild(NioEventLoopGroup.java:87)
    at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:57)
    at io.netty.channel.MultithreadEventLoopGroup.<init>(MultithreadEventLoopGroup.java:49)
    at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:61)
    at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:52)
    at com.anz.axle.direct.engine.pricing.forward.Foo.main(Foo.java:12)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

我想知道是否有人曾经遇到过这个问题。 Netty I使用的版本是netty-all-4.0.15.Final,我在Windows 7 64位上运行Java 1.8.0_102 64位(25.102-b14混合模式)。我已经尝试禁用Windows防火墙for Java可执行文件,但没有任何区别......

提前致谢!

修改 好的..我把它缩小到下面的测试。在我的机器上,有时它可能需要3秒,有时需要1毫秒。我不确定为什么。即使我指定了硬编码端口(显然也随着迭代而改变),它仍然很慢..

  public static void main(String[] args) throws IOException {
        for(int i=0; i<20;i++) {
            final InetAddress address = InetAddress.getByName("127.0.0.1");

            final ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.socket().bind(new InetSocketAddress(address, 0));

            final long start = System.currentTimeMillis();
            final InetSocketAddress inetSocketAddress = new InetSocketAddress(address, serverSocketChannel.socket().getLocalPort());
            SocketChannel.open(inetSocketAddress);
            final long finish = System.currentTimeMillis();
            System.out.println(finish - start);
        }
    }

0 个答案:

没有答案