為什麼使用多線程?
為什麼要用線程呢在什麼時候用到!
呵呵 想理解多線程你就得 搞清楚什麼是併發 什麼是並行 ,概念:在單CPU系統中,系統調度在某一時刻只能讓一個線程運行,雖然這種調試機制有多種形式(大多數是時間片輪巡為主),但無論如何,要通過不斷切換需要運行的線程讓其運行的方式就叫併發(concurrent)。而在多CPU系統中,可以讓兩個以上的線程同時運行,這種可以同時讓兩個以上線程同時運行的方式叫做並行(parallel)。我也有段時間糾結於這裡,無論如何我必須得給你明確一點:在某一個時間點,一個CPU(單)只會運行某一個進程裡的單個線程,所以我們經常稱之為併發,說道同步機制,其雞多線程並未真正實現微觀意義上的同步,進程是一個運行單元,線程則是更小的運行單元,簡而言之,就是進程細分成多個線程,譬如:一個進程A運行需要1s,它就會切換到進程B,但是實現多線程機制後,進程A細化成10個線程,每個線程只需運行0.1s,當然B線程也一樣,這就出現,線程之間的切換時間更短,從宏觀上看就出現同步幻象了。所以學習多線程你得真正理解所謂的同步併發,並不是真正的“同步”。當你理解這些的時候,你就初略的感覺什麼時候該使用多線程機制,其實你的電腦每個程序都至少有一個主線程,那個管理器中的每一個進程,其實內部包含若干線程,每個時間點都是某個程序進程中的某個線程在運行。這些都是我的理解 ,還有不懂的請繼續提出,我會盡量幫你解答。
什麼是線程?它與進程有什麼區別?為什麼要使用多線程
Winform類系統的自動更新就是典型的多進程+多線程的例子。其中進程主要有2個,一個是功能進程,一個是下載進程。即,登陸系統時,打開功能程序,驗證系統的版本,若版本低於服務器版本,就啟動下載進程,將最新版本下載到本地,然後重新打開功能進程。一般大型網遊的更新,更新補丁是一個進程,遊戲運行是另外一個。多線程就很常見了,比如下載補丁更新進度的提示,安裝進度的提示,用的都是多線程技術。即窗體定期刷新進行顯示,而真正的處理在和窗體線程同級的另一個線程中很遺憾,這種東西的跨度比較大,沒有很簡單的例子
為什麼要在應用程序中使用併發和多線程
在早期單核架構的系統中 多線程併發可能並不會比協同之類的有更高的執行效率,但在現代多核時代 多線程可以讓程序更好的應用計算機多核的能力,可以把一部分的計算量分擔到其他cpu上,減少主cpu的計算量從而達到減少運算時間
好處的話 簡單來說就是快
但是壞處也帶來不少 多線程運算 需要注意線程間的調度和協作 需要處理好多線程共享的變量,需要處理好變量鎖 有的時候沒處理好甚至可能導致死鎖或者其他問題
多線程中為什麼要使用Dispatch
iOS中timer相關的延時調用,常見的有NSObject中的performSelector:withObject:afterDelay:這個方法在調用的時候會設置當前runloop中timer,還有一種延時,直接使用NSTimer來配置任務。
這兩種方式都一個共同的前提,就是當前線程裡面需要有一個運行的runloop並且這個runloop裡面有一個timer。
我們知道:只有主線程會在創建的時候默認自動運行一個runloop,並且有timer,普通的子線程是沒有這些的。這樣就帶來一個問題了,有些時候我們並不確定我們的模塊是不是會異步調用到,而我們在寫這樣的延時調用的時候一般都不會去檢查運行時的環境,這樣在子線程中被調用的時候,我們的代碼中的延時調用的代碼就會一直等待timer的調度,但是實際上在子線程中又沒有這樣的timer,這樣我們的代碼就永遠不會被調到。
下面的代碼展示了performSelector和dispatch_time的不同
/
testDispatch_after 延時添加到隊列 /
-(void) testDispatch_after{
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3NSEC_PER_SEC);
dispatch_after(time, dispatch_get_main_queue(), ^{
NSLog(@"3秒後添加到隊列");
});
}
-(void) testDelay{
NSLog(@"3秒後testDelay被執行");
}
/
dispatch_barrier_async 柵欄的作用
*/
-(void) testDispatch_Barrier{
//dispatch_queue_t gcd = dispatch_queue_create("這是序列隊列", NULL);
dispatch_queue_t gcd = dispatch_queue_create("這是併發隊列", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(gcd, ^{
NSLog(@"b0");
//這個selector不會執行
[self performSelector:@selector(testDelay) withObject:nil afterDelay:3];
//代碼會執行
//[self testDispatch_after];
});
dispatch_release(gcd);
}
在有多線程操作的環境中,這樣performSelector的延時調用,其實是缺乏安全性的。我們可以用另一套方案來解決這個問題,就是使用GCD中的dispatch_after來實現單次的延時調用
java中為什麼要用多線程
運用多線程,可以使很多任務同時進行,充分利用cpu的處理效率
為什麼多線程用了一會感覺變慢了
線程也是有開銷的,而且還有同步等操作,所以性能的提升與線程的使用並無直接關係;主要是算法級的如果數據量大 ,那查詢速度會快,畢竟是並行的,可是數據量小的時候,你線程提升的作用有還低不過他的開銷了!性能也不是憑感覺的,要有事實數據!
java程序中線程的概念和使用方法,為什麼要使用多線程技術
拿遊戲舉例,你可以一邊聊天,一邊殺怪。。如果還是像之前一樣的單線程,那就是聊天的時候不能殺怪,殺怪的時候不能聊天,明顯不符合我們的要求。這時候多線程技術就顯得尤為重要了。
多線程的適用場景是什麼?為啥要用多線程
使用多線程是為了提高程序運行的效率。假如有一個程序,要求用戶輸入多個算式,計算出結果,並分別打印到屏幕上。如果用戶一直沒有輸入,那麼無法計算,更無法打印。如果用戶輸入了,必須要全部輸入完,才能計算出結果,再打印到屏幕。
使用線程的話,一個線程用來等待用戶輸入,一個用來計算結果,一個用來打印。用戶在輸入算式3的時候,計算線程在計算算式2,打印線程在打印算式1,三個線程同時進行,減少了等待,這樣就提高了運行效率
多線程的例子,為什麼突然會佔用大量內存
在你的表述中,“線程池不適合用來做耗時的任務”是最大誤區
1)你一定看到過System.Net.Socket類中有很多BeginXXX / EndXXX的方法,例如Socket.BeginReceiveFrom和Socket.EndReceiveFrom,這些函數統稱為異步函數。而異步函數操作的基礎恰恰就是線程池。對Socket通信而言,微軟提供的異步操作正是利用線程池中I/O線程,目的就是為了提高Socket I/O性能並簡化內存管理的!
2)如果對異步操作感到頭暈,在處理Socket操作時可以使用“顯式線程”方法,即按以下方法啟動處理線程:
System.Thread t = new System.Thread(你的處理函數);
t.IsBackground = true; //這個設置尤其重要!!!!!
t.Start();
一定要注意將線程設置為後臺線程!
3)你一定知道系統每次啟動線程和銷燬線程時都會導致很大的開銷。當你的程序頻繁的啟動、銷燬線程,必然會導致程序很“卡”;正是由於這個緣故,微軟才搞了一個“線程池”。因為線程中的線程都是“啟動完畢的”(這樣表述雖不確切,但沒有錯),一旦你將異步處理函數“掛接”的線程池中的空閒線程上即可以執行你要的操作。而且,額外的好處是你根本不用去管理線程池中的線程(真正的“零”管理)
4)處理“耗時的操作”特別是涉及諸如Socket I/O 耗時操作,最佳的處理方法是利用後臺線程(如果需要,同時配合以自定義事件event),這是增加用戶體驗不二法門哦~~
為什麼要使用線程池
為什麼要用線程池?諸如Web 服務器、數據庫服務器、文件服務器或郵件服務器之類的許多服務器應用程序都面向處理來自某些遠程來源的大量短小的任務。請求以某種方式到達服務器,這種方式可能是通過網絡協議(例如 HTTP、FTP 或 POP)、通過 JMS 隊列或者可能通過輪詢數據庫。不管請求如何到達,服務器應用程序中經常出現的情況是:單個任務處理的時間很短而請求的數目卻是巨大的。構建服務器應用程序的一個過於簡單的模型應該是:每當一個請求到達就創建一個新線程,然後在新線程中為請求服務。實際上,對於原型開發這種方法工作得很好,但如果試圖部署以這種方式運行的服務器應用程序,那麼這種方法的嚴重不足就很明顯。每個請求對應一個線程(thread-per-request)方法的不足之一是:為每個請求創建一個新線程的開銷很大;為每個請求創建新線程的服務器在創建和銷燬線程上花費的時間和消耗的系統資源要比花在處理實際的用戶請求的時間和資源更多。除了創建和銷燬線程的開銷之外,活動的線程也消耗系統資源。在一個 JVM 裡創建太多的線程可能會導致系統由於過度消耗內存而用完內存或“切換過度”。為了防止資源不足,服務器應用程序需要一些辦法來限制任何給定時刻處理的請求數目。線程池為線程生命週期開銷問題和資源不足問題提供瞭解決方案。通過對多個任務重用線程,線程創建的開銷被分攤到了多個任務上。其好處是,因為在請求到達時線程已經存在,所以無意中也消除了線程創建所帶來的延遲。這樣,就可以立即為請求服務,使應用程序響應更快。而且,通過適當地調整線程池中的線程數目,也就是當請求的數目超過某個閾值時,就強制其它任何新到的請求一直等待,直到獲得一個線程來處理為止,從而可以防止資源不足。