zoukankan      html  css  js  c++  java
  • Tomcat NIO分析

    tomcat nio并不是真正的异步io,其实是io复用,可以说是非阻塞的,但不是真正的异步。
    tomcat的NioEndpoint启动的ServerSocket是阻塞的,Acceptor线程里边阻塞从accept()获取socket
    socket是非阻塞的,每个socket的channel注册到一个Poller线程上去,Poller会把这个channel包装成一个PollerEvent,并放到events队列里去。

    #默认有两个Poller线程,每个Poller线程里边有一个Selector,以及一个队列:SynchronizedQueue<PollerEvent> events
    btw:Acceptor线程和Poller线程都是NioEndpoint的内部类实现的)

    Poller线程内部不断循环events队列 1、从里边拿出PollerEvent去执行它的run方法,其中将PollerEvent的SocketChannel注册到该poller的Selector中。
    2、SocketChannel如果readable则执行processKey()
    processKey()里边调用processSocket(),processSocket()里边把socket包装成SocketProcessor交给线程池去执行。

    #线程池
    在NioEndpoint的startInternal()方法里,也就是在启动Poller和Acceptor线程之前把线程池建立起来createExecutor()
    //创建线程池
    public void createExecutor() {
    internalExecutor = true;
    TaskQueue taskqueue = new TaskQueue(); //任务队列
    TaskThreadFactory tf = new TaskThreadFactory(getName() + "-exec-", daemon, getThreadPriority());//工程模式,告诉线程池怎么创建里边的线程
    //参数:核心线程数、最大线程数、60秒keepalive、任务队列、以及用来创建线程用的线程工厂
    executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), 60, TimeUnit.SECONDS,taskqueue, tf);
    taskqueue.setParent( (ThreadPoolExecutor) executor);//任务队列里边存了一下线程池的引用,以后会用到
    }

    接下来就是研究TaskQueue、ThreadPoolExecutor了

    看过来其实tomcat线程池还是基于jdk线程池的,只是在初始化的时候传入了自定义的TaskQueue和ThreadFactory, 从而达到自定义线程池的目的。

    最终目的是要分析好两份jstact样本:
    异常,将近400个处于WAITING
    "http-nio-8081-exec-385" #459 daemon prio=5 os_prio=0 tid=0x00007f4b6819a800 nid=0x674e waiting on condition [0x00007f4b2e977000]
    java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for <0x00000006c8ddb088> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2083)
    at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
    at org.apache.tomcat.util.threads.TaskQueue.poll(TaskQueue.java:85)
    at org.apache.tomcat.util.threads.TaskQueue.poll(TaskQueue.java:31)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1073)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
    正常样本: 无请求时,tomcat线程池中idle线程10个,等待处理请求
    "http-nio-8081-exec-1" #17 daemon prio=5 os_prio=0 tid=0x00007f3bf8aa9800 nid=0x15d0 waiting on condition [0x00007f3bd54d4000]
    java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for <0x00000000e41b3ad8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
    at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

    to be continuted ...

  • 相关阅读:
    Oracle to_char格式化函数
    电脑快捷键大全
    Failed to create the Java Virtual Machine (Myeclipse或者eclipse启动报错)
    Java 面试题
    UVA1108 Mining Your Own Business
    无向图的连通性
    [NOI Online #2 提高组]子序列问题
    [NOI Online #3 提高组]优秀子序列
    POJ2430 Lazy Cows
    UVA1633 Dyslexic Gollum
  • 原文地址:https://www.cnblogs.com/lyhero11/p/12256757.html
Copyright © 2011-2022 走看看