91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Tomcat如何進行并發編程

發布時間:2021-08-25 16:43:01 來源:億速云 閱讀:155 作者:chen 欄目:大數據

這篇文章主要講解了“Tomcat如何進行并發編程”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Tomcat如何進行并發編程”吧!

首先是最常用的synchronized

在容器的啟動流程中,會從Server開始一直向到各個下層容器進行啟動,下面的代碼是Server找到配置的Service,進行遍歷啟動

private final Object servicesLock = new Object();

// Start our defined Services

       synchronized (servicesLock) {

           for (int i = 0; i < services.length; i++) {

               services[i].start();

           }

       }

其次,是鎖范圍的減小

service的啟動過程,其實是這樣的

 protected void startInternal() throws LifecycleException {

               // Start our defined Container first

               if (container != null) {

                   synchronized (container) {

                       container.start();

                   }

               }

               synchronized (executors) {

                   for (Executor executor: executors) {

                       executor.start();

                   }

               }

           }

上面的代碼,我們看到,并不是整個方法進行加鎖,而是對于各個容器內組件的啟動進行分別加鎖。這種對于鎖作用范圍和持有時間的縮小,可以降低鎖競爭,提升可伸縮性。當然,如果說所有的內容都分別加鎖反而會影響性能。感興趣的朋友可以閱讀Java并發編程實戰的性能與可伸縮性一章,了解更多內容。

線程池啟動容器內組件

// Start our child containers, if any

Container children[] = findChildren();

List<Future<Void>> results = new ArrayList<>();

for (int i = 0; i < children.length; i++) {

    results.add(startStopExecutor.submit(new StartChild(children[i])));

}


boolean fail = false;

for (Future<Void> result : results) {

    try {

        result.get();

    } catch (Exception e) {

 }}

各個容器獲取到其子組件后,將其組裝成一個任務,提交到任務執行線程池中。任務的執行結果,在通過其Future對象獲取。

通過Callable封裝帶返回值的任務

private static class StartChild implements Callable<Void> {

        private Container child;

        public StartChild(Container child) {

            this.child = child;

        }

        public Void call() throws LifecycleException {

            child.start();

            return null;

   } }

由于組件的啟動并不需要返回值,此處使用Void類型,可以在實際使用過程中換成具體的值返回具體的結果。在全部任務執行完成后,從Future中get返回值。

Volatile的使用

  private volatile boolean close = false;

  // Time to terminate?

       if (close) {

          timeout(0, false);

       try {

            selector.close();

       } catch (IOException ioe) {

  }

通過使用volatile值,來保證多線程環境中關閉標識的可見性,從而能正確的在標識改變后退出特定邏輯。

wait/notify的使用

在前面的概念中,我們提到使用wait/notify的時候,一定要在拿到鎖的情況下進行。Tomcat在進行Servlet實例allocate和deallocate的時候,會使用到這兩個操作。

      synchronized (instancePool)

         while (countAllocated.get() >= nInstances) {

             if (nInstances < maxInstances) {

                 instancePool.push(loadServlet());

                 nInstances++;

             } else {

                 instancePool.wait();

             }

   }

卸載的時候,代碼是這樣的

         synchronized (instancePool) {

             countAllocated.decrementAndGet();

             instancePool.push(servlet);

             instancePool.notify();

         }

兩種情況都是先拿到鎖再進行的。

當然,Tomcat中也有許多對JDK并發包內組件的使用,像下面這個對于CountDownLatch的使用

private volatile CountDownLatch stopLatch = null; 

 stopLatch = new CountDownLatch(pollerThreadCount); // 在Endpoint進行bind操作時,設置相應poller數量的CountDownLatch


// 在處理destory時,進行countDown操作,后續的關閉操作,會根據stopLatch的數據進行等待操作。

stopLatch.countDown();

感謝各位的閱讀,以上就是“Tomcat如何進行并發編程”的內容了,經過本文的學習后,相信大家對Tomcat如何進行并發編程這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

三门县| 黄石市| 元阳县| 武平县| 油尖旺区| 镇宁| 行唐县| 北票市| 喜德县| 郯城县| 乡宁县| 天峻县| 铜川市| 宜春市| 贺兰县| 根河市| 江门市| 大荔县| 法库县| 乡城县| 泽州县| 丹阳市| 登封市| 封开县| 湄潭县| 绥江县| 嵩明县| 通渭县| 崇左市| 怀集县| 当涂县| 惠安县| 霍林郭勒市| 广元市| 驻马店市| 柏乡县| 泾阳县| 平潭县| 怀仁县| 富顺县| 金湖县|