線程理解

在面試的時候被問了一個多線程的問題 
回來仔細思考了一下,多線程是否真的能提高了效率? 
我對多線程的理解就是: 
比如挖一個隧道,有2種開工方法 
1、只在山的一頭挖,直至挖到山的另一頭,從而打通隧道,這可以看成是單線程 

2、在山的兩頭挖,同時開工,最後在山的中間接通,從而打通隧道,這感覺肯定比1快了很多,好比多線程 

但是2成立的前提是必須有兩個工人。而我們的計算機中一般來說只有一個CPU,也就是說只有一個工人。 
多線程不過是CPU在不同的時間片之間切換,而表現出齊頭並進的樣子。 

既然挖隧道的人只有一個,雖然我的施工方案是在山的兩頭開挖,但是由於工作的人只有一個,所以只有讓這個人在山的兩頭跑,挖一會這頭再去挖另一頭,來回跑是要花費額外時間的(好比線程的切換和調度)。 

那麼,我們是不是可以說,在單CPU的機器中,多線程反而降低了效率呢?

1.
不能一概而論,你的看多線程在你的程序中爲啥而生。在單cpu系統,比如有io的等待,多線程也能提高效率 
2
樓主提的問題很有意思。經典的解釋是 - 如果cpu確實是一個挖山工人,那麼它工作就好像是挖1個小時,然後休息10個小時;這期間如果讓它跑到山那頭繼續挖,效率還是很高的。

現在問題是 - 它是否工作1小時然後休息10小時?答案是肯定的。現在的程序時間大多花在讀取數據上,真正的計算工作花時間還是相對少的,因此cpu很大時間表現都很閒,就像挖山,挖土效率高,運土效率低。多線程就是要充分利用它的挖土效率 
3
pc機不光只一個cpu,cpu和其它硬件設備一起才能完成計算,分工協作,但可能出現其中某個傢伙偷懶或效率低,導致大家都等它,閒着的其它設備這個時 候可以騰出手來幹其它活。單cpu在同一時刻只能幹一件事情,這沒有問題,問題是它並不是7*24*3600都在幹活,其它設備也是同樣的道理,多線程的 目的可以最大限度的提高硬件設備的利用率。
4
同一個設備可以同時幹幾件事情,但一個設備在同一時刻肯定只能幹一件事情,一般我們說並行或串行,都在以時間段來看的而不是以時刻來看的,比如你一邊上je消遣還一邊寫代碼幹活,在一定的時間範圍內,你是並行的,但如果這個時間範圍你劃分得非常非常短,那麼你是串行的 

5
一個cpu可以多線程。但是一個單核的cpu任何時間點,都只能在做一個任務。 
如果只是像樓主說的挖隧道這麼簡單的事,那麼的確多線程沒用。 
只不過很可惜,計算機不像拿鐵鍬挖隧道這麼簡單。 

6
假設每挖5分鐘,就需要清理一下挖出來的石土。有一個小車在清理它們。 
工人只有一個。 
單線程的做法是: 挖5分鐘。然後工人停止挖,小車清理石土的5分鐘裏,工人在等待。 
2個線程的做發是: 挖5分鐘,小車來清理石土。這5分鐘裏,工人在另一頭挖。 

也不是很恰當的比喻。不過至少能說明點問題。 
小車清理石土,就相當於磁盤io等相對於cpu計算來說比較慢的操作。 

cpu不會等着io的完成,而去執行另一個進程的計算任務。 
這邊io完成時好象是會發出什麼信號來着,忘了。計算機原理都還給老師了,慚愧啊。 
7

如樓主所舉的例子,我來解惑。 

如果一個機器人代表CUP,哪麼這個機器人一天所做的事情,並不都是隻挖山。 

它還有許多事情要做,比如砍柴,燒水,釣魚,挖山等等等。 

如果按以上劃分是 4條線程, 每一個線程大概佔用1/4CUP時間。 

如果你的設定 在挖山這一快 多設幾次同一個任務。 比如設定到 挖山共有3條線程。 

哪麼 挖山的CUP佔用率將達到 1/2 這就是所謂的提高了效率。 

現實中的CPU 在大部分時候的 閒置狀態的。 
因此 開多條線程能提高效率 不如說成是 充分利用了CPU執行時間。 

8
樓主舉的例子是並行,在資源有剩餘的情況下(比如人都堆到一個洞裏幹不開),肯定是提高效率。如果資源有衝突(人手只夠從一個方向挖,比如只一個CPU),那就是併發了,不一定能提高效率。 

我想了個例子: 
    假設人手只夠從一個方向挖洞。 
    挖洞時,總得把洞裏的土運出去吧。洞越深,運土越佔用時間,如果一大夥人都在那挖洞,等挖出一車土,然後一起坐着車運土(帶裝卸),那路上那些人就閒着了 (挖土時司機也會閒着)。爲了提高工作效率,那就把人分成三組,一組人(一個挖土線程)挖土,兩組人運土(兩輛車,兩個運土線程)。

9

我認爲啊,單CPU單核、純計算、沒IO的理想狀態下,單個線程肯定比多個線程快,因爲省去了線程切換的開銷。但真實的環境基本都有IO操作,在 異步的業務場景下,我一般會使用線程池,至於線程池的線程數目配置爲多少,有資料推薦爲N×(1+IO耗時/完整的業務耗時),N是CPU核數。

10
最簡單的如web server,如果單線程的話,一個server同時只能接受一個用戶的點擊。
還點擊率呢,直接就綠了。
另外多線程和快不快沒有直接關係。最主要的是可以併發執行。
純粹比較同一個任務在單線程還是多線程模式下快的話,肯定是單線程快。因爲多線程會有一個線程調度的消耗。但是最爲一個系統,多線程的優勢是非常明顯的。如果Java沒有多線程直接可以去死了。
當年紅極一時的plam系統因爲對多線程支持的不好,在網絡和媒體應用方面敗下陣來。 

11

多線程效率 我認爲未必會高,而且有時候相反會低。 
多線程並不是爲了提高效率,而是不必等待 可以並行執行多條數據。 
可以這麼想 我們通過xp系統複製文件。你可以複製一份文件 這叫是單線呈,但是你要等這個複製完了才能複製另一份文件,而且不能多複製。這樣很難受,所以你可以選擇多複製文件,這就是多線程。但複製多份文件用的時 間未必會比一份一份文件所用時間少。只是它合理利用了時間進行了多個操作。 
    如果是買票系統 就會用到多線呈。買票是同時進行的,如果一個用戶一個用戶等下去不是辦法,所以可以多個用戶同時買票,效率也就提高了。這裏的效率不是執行的效率 而是時間的合理利用,多個線呈同時進行。 

12
單線程,多線程,線程池,都是不同問題的不同解決策略,不存在誰的效率一定高的問題.

一個時間服務器,一個線程處理請求就可以了
FTP,HTTP服務器,就不一樣了,請求多,處理響應時間長,必須得有多個線程來處理,
線程池是多線程的一種改良方式
當然以上指的都是BIO的情況.
在NIO下,處理請求用單線程就可以了,因爲它不存在IO阻塞的問題 

13
樓主的例子舉的還算生動,但思路有點問題。在大多數場景中,各個線程不應該是同時去做同一件事情,而是各謀其職,協調工作,從而最大限度的利用系統資源。而系統資源並不僅僅是CPU,還有I/O或帶寬等等。 

就樓主的例子而言,可以想象成兩個線程,A線程的任務是挖,B線程的任務是把挖開的土石運走,從而提高效率,這也就是經典的生產者消費者模式。 

14
生產者-消費者模型,如果你是用多線程實現了的,那完全也可以寫成單線程的(當然,單線程也就是一個順序執行,恐怕不能稱爲“生產-消費”了)。 
    之所以設計成生產者-消費者的模式,是因爲生產者和消費者不能步調一致吧?!因爲會出現等待的情況,所以要按“生產者-消費者”的方式,用多線程實現(比 如3個生產者線程,2個消費者線程)。這充分利用了系統資源,如果效率還沒有提高,那真不知道要幹啥呢——比如說,生產者乾的事就是 a+1,消費者乾的事就是a-1,那何必費勁做成“生產者-消費者”呢(專門做出一個生產者線程對一個消費者線程,也太傻了吧)? 

    上面已經有人說了,系統運行環境下的資源並不只有CPU,還有網絡,數據庫(可能安裝在另一個機器上)。數據庫訪問和網絡的IO操作都是比較耗時的,這時候CPU會閒一些。使用多線程可以調配資源的使用率。 
    
    PS:假設你的程序部署到一個配置特牛的服務器上,感覺還是不足以應付業務量,結果一查CPU佔用率,才3%,你的程序是不是寫的很失敗? 

15
我覺得lz舉的例子不太合適,一個CPU它不是一個工人,按WINDOWS的比喻,一個CPU應該是100個工人. 
100個工人挖山從一頭挖,最多同時能20個人一起挖,其他80個人休息.(這是單線程) 
如果兩頭挖,最多同時40人一起挖,60個人休息.(這是多線程) 
所以多線程只能提高CPU的使用效率. 
一頭挖山只使用CPU的20%,兩頭挖山可能就會使用CPU的50%,因爲啓動一條新的線程也會有CUP開銷. 
如果在工人足夠多的時候,用多多線程,是可以提前完工的. 
如果在工人不足的時候,只能用單線程. 
聲明下一個CPU它不是一個人!!! 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章