多線(xiàn)程使用的主要目的在于:1、吞吐量:你做WEB,容器幫你做了多線(xiàn)程,但是他只能幫你做請(qǐng)求層面的。簡(jiǎn)單的說(shuō),可能就是一個(gè)請(qǐng)求一個(gè)線(xiàn)程。或多個(gè)請(qǐng)求一個(gè)線(xiàn)程。如果是單線(xiàn)程,那同時(shí)只能處理一個(gè)用戶(hù)的請(qǐng)求。2、伸縮性:也就是說(shuō),你可以通過(guò)增加CPU核數(shù)來(lái)提升性能。如果是單線(xiàn)程,那程序執(zhí)行到死也就利用了單核,肯定沒(méi)辦法通過(guò)增加CPU核數(shù)來(lái)提升性能。
鑒于是做WEB的,第1點(diǎn)可能你幾乎不涉及。那這里我就講第二點(diǎn)吧。fileName2Data=newHashMap(); privatevoidprocessFile3(StringfName){ Stringdata=fileName2Data.get(fName); if(data==null){ data=readFromFile(fName);//耗時(shí)28ms fileName2Data.put(fName,data); } //processwithdata } }
看起來(lái)好像還不錯(cuò),建立一個(gè)文件名和文件數(shù)據(jù)的映射。如果讀取一個(gè)map中已經(jīng)存在的數(shù)據(jù),那么就不不用讀取文件了。
可是問(wèn)題在于,Servlet是并發(fā),上面會(huì)導(dǎo)致一個(gè)很?chē)?yán)重的問(wèn)題,死循環(huán)。因?yàn)椋琀ashMap在并發(fā)修改的時(shí)候,可能是導(dǎo)致循環(huán)鏈表的構(gòu)成!?。。ň唧w你可以自行閱讀HashMap源碼)如果你沒(méi)接觸過(guò)多線(xiàn)程,可能到時(shí)候發(fā)現(xiàn)服務(wù)器沒(méi)請(qǐng)求也巨卡,也不知道什么情況!
好的,那就用ConcurrentHashMap,正如他的名字一樣,他是一個(gè)線(xiàn)程安全的HashMap,這樣能輕松解決問(wèn)題。fileName2Data=newConcurrentHashMap(); privatevoidprocessFile3(StringfName){ Stringdata=fileName2Data.get(fName); if(data==null){ data=readFromFile(fName);//耗時(shí)28ms fileName2Data.put(fName,data); } //processwithdata } }
這樣真的解決問(wèn)題了嗎,這樣雖然只要有用戶(hù)訪(fǎng)問(wèn)過(guò)文件a,那另一個(gè)用戶(hù)想訪(fǎng)問(wèn)文件a,也會(huì)從fileName2Data中拿數(shù)據(jù),然后也不會(huì)引起死循環(huán)。最新 Java 面試題出爐!分享給你。
可是,如果你覺(jué)得這樣就已經(jīng)完了,那你把多線(xiàn)程也想的太簡(jiǎn)單了,騷年!你會(huì)發(fā)現(xiàn),1000個(gè)用戶(hù)首次訪(fǎng)問(wèn)同一個(gè)文件的時(shí)候,居然讀取了1000次文件(這是最極端的,可能只有幾百)。What the ***in hell!!!
難道代碼錯(cuò)了嗎,難道我就這樣過(guò)我的一生!
好好分析下。Servlet是多線(xiàn)程的,那么fileName2Data=newConcurrentHashMap(); privatevoidprocessFile3(StringfName){ Stringdata=fileName2Data.get(fName); //“偶然”--1000個(gè)線(xiàn)程同時(shí)到這里,同時(shí)發(fā)現(xiàn)data為null if(data==null){ data=readFromFile(fName);//耗時(shí)28ms fileName2Data.put(fName,data); } //processwithdata } }
上面注釋的“偶然”,這是完全有可能的,因此,這樣做還是有問(wèn)題。
因此,可以自己簡(jiǎn)單的封裝一個(gè)任務(wù)來(lái)處理。fileName2Data=newConcurrentHashMap(); privatestaticExecutorServiceexec=Executors.newCacheThreadPool(); privatevoidprocessFile3(StringfName){ FutureTaskdata=fileName2Data.get(fName); //“偶然”--1000個(gè)線(xiàn)程同時(shí)到這里,同時(shí)發(fā)現(xiàn)data為null if(data==null){ data=newFutureTask(fName); FutureTaskold=fileName2Data.putIfAbsent(fName,data); if(old==null){ data=old; }else{ exec.execute(data); } } Stringd=data.get(); //processwithdata } privateFutureTasknewFutureTask(finalStringfile){ returnnewFutureTask(newCallable(){ publicStringcall(){ returnreadFromFile(file); } privateStringreadFromFile(Stringfile){return"";} } } }
以上所有代碼都是直接在bbs打出來(lái)的,不保證可以直接運(yùn)行。
多線(xiàn)程最多的場(chǎng)景:web服務(wù)器本身;各種專(zhuān)用服務(wù)器(如游戲服務(wù)器);
舉個(gè)簡(jiǎn)單的例子:
假設(shè)有個(gè)請(qǐng)求,這個(gè)請(qǐng)求服務(wù)端的處理需要執(zhí)行3個(gè)很緩慢的IO操作(比如數(shù)據(jù)庫(kù)查詢(xún)或文件查詢(xún)),那么正常的順序可能是(括號(hào)里面代表執(zhí)行時(shí)間):- 讀取文件1 (10ms)
- 處理1的數(shù)據(jù)(1ms)
- 讀取文件2 (10ms)
- 處理2的數(shù)據(jù)(1ms)
- 讀取文件3 (10ms)
- 處理3的數(shù)據(jù)(1ms)
- 整合1、2、3的數(shù)據(jù)結(jié)果 (1ms)
- 讀取文件1 (1ms)
- 處理1的數(shù)據(jù)(1ms)
- 讀取文件2 (1ms)
- 處理2的數(shù)據(jù)(1ms)
- 讀取文件3 (28ms)
- 處理3的數(shù)據(jù)(1ms)
- 整合1、2、3的數(shù)據(jù)結(jié)果 (1ms)
偽代碼:
publicclassMyServletextendsServlet{ privatestaticMap
publicclassMyServletextendsServlet{ privatestaticConcurrentHashMap
publicclassMyServletextendsServlet{ privatestaticConcurrentHashMap
publicclassMyServletextendsServlet{ privatestaticConcurrentHashMap
審核編輯 :李倩
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀(guān)點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。
舉報(bào)投訴
-
服務(wù)器
+關(guān)注
關(guān)注
14文章
10292瀏覽量
91583 -
JAVA
+關(guān)注
關(guān)注
20文章
3002瀏覽量
116581 -
多線(xiàn)程
+關(guān)注
關(guān)注
0文章
279瀏覽量
21072
原文標(biāo)題:面試官:公司項(xiàng)目中Java的多線(xiàn)程一般用在哪些場(chǎng)景?
文章出處:【微信號(hào):AndroidPush,微信公眾號(hào):Android編程精選】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
熱點(diǎn)推薦
Java多線(xiàn)程的用法
本文將介紹一下Java多線(xiàn)程的用法。 基礎(chǔ)介紹 什么是多線(xiàn)程 指的是在一個(gè)進(jìn)程中同時(shí)運(yùn)行多個(gè)線(xiàn)程
Java一直獨(dú)得恩寵的秘訣
Java中沒(méi)有指針,這樣就沒(méi)有辦法直接訪(fǎng)問(wèn)內(nèi)存了。另外Java也不容易出現(xiàn)內(nèi)存泄露。而且Java確實(shí)有很多企業(yè)在用,都是用在大項(xiàng)目上。這就意
發(fā)表于 09-28 14:24
java多線(xiàn)程編程實(shí)例 (源程序)
java多線(xiàn)程編程實(shí)例
import java.awt.*;import javax.swing.*;
public class CompMover extends Object { 
發(fā)表于 10-22 11:48
?0次下載
java多線(xiàn)程設(shè)計(jì)模式_結(jié)城浩
《JAVA多線(xiàn)程設(shè)計(jì)模式》通過(guò)淺顯易懂的文字與實(shí)例來(lái)介紹JAVA線(xiàn)程相關(guān)的設(shè)計(jì)模式概念,并且通過(guò)實(shí)際的JAVA程序范例和UML圖示來(lái)一一解說(shuō)
發(fā)表于 01-05 16:15
?0次下載
一些java 多線(xiàn)程面試題
問(wèn)題比較簡(jiǎn)單,可以用join方法實(shí)現(xiàn)。 2. 在Java中Lock接口比synchronized塊的優(yōu)勢(shì)是什么?你需要實(shí)現(xiàn)一個(gè)高效的緩存,它允許多個(gè)用戶(hù)讀,但只允許一個(gè)用戶(hù)寫(xiě),以此來(lái)保持它的完整性,你會(huì)怎樣去實(shí)現(xiàn)它? lock接
發(fā)表于 09-28 14:18
?0次下載
Java多線(xiàn)程總結(jié)之Queue
在Java多線(xiàn)程應(yīng)用中,隊(duì)列的使用率很高,多數(shù)生產(chǎn)消費(fèi)模型的首選數(shù)據(jù)結(jié)構(gòu)就是隊(duì)列。Java提供的線(xiàn)程安全的Queue可以分為 阻塞隊(duì)列和非阻塞隊(duì)列 ,其中阻塞隊(duì)列的典型例子
發(fā)表于 11-28 16:14
?3860次閱讀
java學(xué)習(xí)——java面試【事務(wù)、鎖、多線(xiàn)程】資料整理
本文檔內(nèi)容介紹了基于java學(xué)習(xí)java面試【事務(wù)、鎖、多線(xiàn)程】資料整理,供參考
發(fā)表于 03-13 13:53
?0次下載
滌綸電容一般用在哪里?
二者是有區(qū)別的!滌綸電容又叫聚酯電容符號(hào)為CL,電容量一般40p--4μ, 額定電壓63--630V,主要特點(diǎn)體積小容量大耐熱耐濕但穩(wěn)定性差一般應(yīng)用在對(duì)穩(wěn)定性和損耗要求不高的低頻電路。
發(fā)表于 11-13 09:51
?5133次閱讀
Java多線(xiàn)程永動(dòng)任務(wù) 多線(xiàn)程異步任務(wù)項(xiàng)目解讀
, 這個(gè)示例的原型是公司自研的多線(xiàn)程異步任務(wù)項(xiàng)目 ,我把里面涉及到多線(xiàn)程的代碼抽離出來(lái),然后進(jìn)行一定的改造。 里面涉及的知識(shí)點(diǎn)非常多,特別適
多線(xiàn)程編程可以應(yīng)用在哪里?C++多線(xiàn)程詳解
多線(xiàn)程并發(fā)指的是在同一個(gè)進(jìn)程中執(zhí)行多個(gè)線(xiàn)程。 優(yōu)點(diǎn): 有操作系統(tǒng)相關(guān)知識(shí)的應(yīng)該知道,線(xiàn)程是輕量級(jí)的進(jìn)程,每個(gè)線(xiàn)程可以獨(dú)立的運(yùn)行不同的指令序列
發(fā)表于 04-13 10:10
?1115次閱讀
紐扣型超級(jí)電容器一般是用在哪里?
紐扣型超級(jí)電容器一般是用在哪里?即便是同一種類(lèi)型的產(chǎn)品,其型號(hào)、規(guī)格以及作用都是不同的。所以,大家在選擇產(chǎn)品的時(shí)候,也要從細(xì)節(jié)方面來(lái)考慮。紐扣型超級(jí)電容器在市場(chǎng)上是很常見(jiàn)的,它被應(yīng)用在
java實(shí)現(xiàn)多線(xiàn)程的幾種方式
Java實(shí)現(xiàn)多線(xiàn)程的幾種方式 多線(xiàn)程是指程序中包含了兩個(gè)或以上的線(xiàn)程,每個(gè)線(xiàn)程都可以并行執(zhí)行不同的任務(wù)或操作。
公司項(xiàng)目中Java的多線(xiàn)程一般用在哪些場(chǎng)景?
評(píng)論