多線程編程
Ⅰ 什麼是多線程編程什麼時候使用
多線程的使用主要是用來處理程序「在一部分上會阻塞」,「在另一部分上需要持續運行」的場合。一般是根據需求,可以用多線程,事件觸發,callback等方法達到。但是有一些方法是只有多線程能辦到的就只有用多線程或者多進程來完成。
舉個簡單的例子,能理解就行。假設有這樣一個程序,
1會不停的處理收到的所有TCP請求。對於每個TCP請求做不同的操作。不能有遺漏
2有很多特定的請求會向一個伺服器發送存儲的數據,或者是等待用戶輸入。
來看看。第1個要求很簡單。用個while循環就搞定了。但第2個特性呢。一旦在等待用戶輸入或者是連接伺服器時,程序會「阻塞」一段時間,這一段時間內就無法處理其他的TCP請求了。
所以可以利用多線程,每個線程處理不同的TCP請求。這樣程序就不會「阻塞」掉了。
Ⅱ 多線程編程中遵循哪些的最佳實踐
因為 java 中讀取 long 類型變數不是原子的,需要分成兩步,
如果一個線程正在修改該 long 變數的值,另一個線程可能只能看到該值的一半(前 32 位)。
但是對一個 volatile 型的 long 或 double 變數的讀寫是原子。
Ⅲ 什麼是Java多線程編程
一、 什麼是多線程:
我們現在所使用操作系統都是多任務操作系統(早期使用的DOS操作系統為單任務操作系統),多任務操作指在同一時刻可以同時做多件事(可以同時執行多個程序)。
多進程:每個程序都是一個進程,在操作系統中可以同時執行多個程序,多進程的目的是為了有效的使用CPU資源,每開一個進程系統要為該進程分配相關的系統資源(內存資源)
多線程:線程是進程內部比進程更小的執行單元(執行流|程序片段),每個線程完成一個任務,每個進程內部包含了多個線程每個線程做自己的事情,在進程中的所有線程共享該進程的資源;
主線程:在進程中至少存在一個主線程,其他子線程都由主線程開啟,主線程不一定在其他線程結束後結束,有可能在其他線程結束前結束。Java中的主線程是main線程,是Java的main函數;
繼承Thread類來實現多線程:
二、 Java中實現多線程的方式:
當我們自定義的類繼承Thread類後,該類就為一個線程類,該類為一個獨立的執行單元,線程代碼必須編寫在run()方法中,run方法是由Thread類定義,我們自己寫的線程類必須重寫run方法。
run方法中定義的代碼為線程代碼,但run方法不能直接調用,如果直接調用並沒有開啟新的線程而是將run方法交給調用的線程執行
要開啟新的線程需要調用Thread類的start()方法,該方法自動開啟一個新的線程並自動執行run方法中的內容
java多線程的啟動順序不一定是線程執行的順序,各個線程之間是搶佔CPU資源執行的,所有有可能出現與啟動順序不一致的情況。
CPU的調用策略:
如何使用CPU資源是由操作系統來決定的,但操作系統只能決定CPU的使用策略不能控制實際獲得CPU執行權的程序。
線程執行有兩種方式:
1.搶占式:
目前PC機中使用最多的一種方式,線程搶佔CPU的執行權,當一個線程搶到CPU的資源後並不是一直執行到此線程執行結束,而是執行一個時間片後讓出CPU資源,此時同其他線程再次搶佔CPU資源獲得執行權。
2.輪循式;
每個線程執行固定的時間片後讓出CPU資源,以此循環執行每個線程執行相同的時間片後讓出CPU資源交給下一個線程執行。
希望對您有所幫助!~
Ⅳ 多線程編程怎麼回事啊
每個正在系統上運行的程序都是一個進程。每個進程包含一到多個線程。進程也可能是整個程序或者是部分程序的動態執行。線程是一組指令的集合,或者是程序的特殊段,它可以在程序里獨立執行。也可以把它理解為代碼運行的上下文。所以線程基本上是輕量級的進程,它負責在單個程序里執行多任務。通常由操作系統負責多個線程的調度和執行。
什麼是多線程?
多線程是為了使得多個線程並行的工作以完成多項任務,以提高系統的效率。線程是在同一時間需要完成多項任務的時候被實現的。
使用線程的好處有以下幾點:
·使用線程可以把占據長時間的程序中的任務放到後台去處理
·用戶界面可以更加吸引人,這樣比如用戶點擊了一個按鈕去觸發某些事件的處理,可以彈出一個進度條來顯示處理的進度
·程序的運行速度可能加快
·在一些等待的任務實現上如用戶輸入、文件讀寫和網路收發數據等,線程就比較有用了。在這種情況下我們可以釋放一些珍貴的資源如內存佔用等等。
還有其他很多使用多線程的好處,這里就不一一說明了。
一些線程模型的背景
我們可以重點討論一下在Win32環境中常用的一些模型。
·單線程模型
在這種線程模型中,一個進程中只能有一個線程,剩下的進程必須等待當前的線程執行完。這種模型的缺點在於系統完成一個很小的任務都必須佔用很長的時間。
·塊線程模型(單線程多塊模型STA)
這種模型里,一個程序里可能會包含多個執行的線程。在這里,每個線程被分為進程里一個單獨的塊。每個進程可以含有多個塊,可以共享多個塊中的數據。程序規定了每個塊中線程的執行時間。所有的請求通過Windows消息隊列進行串列化,這樣保證了每個時刻只能訪問一個塊,因而只有一個單獨的進程可以在某一個時刻得到執行。這種模型比單線程模型的好處在於,可以響應同一時刻的多個用戶請求的任務而不只是單個用戶請求。但它的性能還不是很好,因為它使用了串列化的線程模型,任務是一個接一個得到執行的。
·多線程塊模型(自由線程塊模型)
多線程塊模型(MTA)在每個進程里只有一個塊而不是多個塊。這單個塊控制著多個線程而不是單個線程。這里不需要消息隊列,因為所有的線程都是相同的塊的一個部分,並且可以共享。這樣的程序比單線程模型和STA的執行速度都要塊,因為降低了系統的負載,因而可以優化來減少系統idle的時間。這些應用程序一般比較復雜,因為程序員必須提供線程同步以保證線程不會並發的請求相同的資源,因而導致競爭情況的發生。這里有必要提供一個鎖機制。但是這樣也許會導致系統死鎖的發生。
Ⅳ 什麼是多線程,多線程編程的好處是什麼
舉個例子,你要做飯,你要做的飯是米飯和一個炒菜。
如果是單線程,那麼你可以如下做:
第一種方法:先炒菜,然後開始蒸米飯;
第二種方法:先蒸米飯,等米飯熟了再炒菜;
如果是多線程,那麼你就可以如下做:
先蒸米飯,在蒸米飯的過程中去炒菜。
有些問題的解決用多線程會提高效率,比如上邊的例子。但是有時不會提高效率,反而會影響效率:
比如,你要洗衣服,還打算做家庭作業(假設你是小學生,老師給你布置的家庭作業)。
如果是單線程:你要麼洗完衣服做作業,要麼做完作業洗衣服。
如果是多線程:你洗一分鍾衣服做一分鍾作業,交叉進行,顯然有些時間都耗在了任務的切換上了。
所以,多線程主要用於,當一個任務需要不佔用資源的等待的時候,可以使用空閑的資源
Ⅵ 什麼是多線程編程
多線程編程技術是Java語言的重要特點。多線程編程的含義是將程序任務分成幾個並行的子任務。特別是在網路編程中,你會發現很多功能是可以並發執行的。 比如網路傳輸速度較慢、用戶輸入速度較慢,你可以用兩個獨立的線程去完成這兩個功能,而不影響正常的顯示或其它功能。 多線程是與單線程比較而言的,普通的Windows採用單線程程序結構,其工作原理是:主程序有一個消息循環,不斷從消息隊列中讀入消息來決定下一步所要乾的事情,一般是針對一個函數,只有等這個函數執行完之後,主程序才能接收另外的消息來執行。比如子函數功能是在讀一個網路數據,或讀一個文件,只有等讀完這個數據或文件才能接收下一個消息。在執行這個子函數過程中你什麼也不能幹。但往往讀網路數據和等待用戶輸入有很多時間處於等待狀態,多線程利用這個特點將任務分成多個並發任務後,就可以解決這個問題。Java中的線程類 1.擴展java.lang.Thread類,用它覆蓋Thread類的run方法。 2.生成實現java.lang.Runnable介面的類並將其它的實例與java.lang.Thread實例相關聯。 Thread類是負責向其它類提供線程支持的最主要的類,要使用一個類具有線程功能,在Java中只要簡單地從Thread類派生一個子類就可以了擴展Thread類,如printThread.java。 Thread類最重要的方法是run方法。run方法是新線程執行的方法,因此生成java.lang.Thread的子類時,必須有相應的run方法。 //PrintThread.java public class PrintThread extends Thread//繼承Tread類 private int count=0 //定義一個count變數用於統計列印的次數並共享變數 public static void mainString args//main方法開始 PrintThread p=new PrintThread//創建一個線程實例 p.start//執行線程 for{;;}//主線程main方法執行一個循環,for執行一個死循環count++ System.out.printcount+″:Main\n″//主線程中列印count +「main」變數的值,並換行 public void run//線程類必須有的run()方法for{;;}count++ System.out.printcount+″:Thread\n″ 上面這段程序便是繼承java.lang.Tread並覆蓋run的方法。用Java 虛擬機啟動程序時,這個程序會先生成一個線程並調用程序主類的main方法。這個程序中的main方法生成新線程,連接列印「Thread」。在啟動線程之後,主線程繼續列印「Main」。 編譯並執行這個程序,然後立即按「Ctrl+C」鍵中斷程序,你會看到上面所述的兩個線程不斷列印出:XXX:main…..XXX:Thread…. XXX代表的是數字,也就是上面count的值。在筆者的機器上,不同時刻這兩個線程列印的次數不一樣,先列印20個main(也就是先執行20次主線程)再列印出50次Thread,然後再列印main…… 提示:為了便於查看該程序的執行結果,你可以將執行結果導入一個文本文件,然後打開這個文件查看各線程執行的情況。如運行: javac PrintThread.java Java PrintThread1.txt 第一個命令javac PrintThread.java是編譯java程序,第二個是執行該程序並將結果導入1.txt文件。當然你可以直接執行命令:java
Ⅶ 並發編程和多線程編程一樣嗎
並發編程又叫多線程編程。
在程序中,往往有很多很耗時的工作,比如上傳文件、下載文件、跟客戶聊天需要長時間建立連接。這種時候,一個線程是服務不了多個用戶的,會產生因為資源獨占產生的等待問題。
例如:編寫一個耗時的單線程程序:
新建一個基於對話框的應用程序SingleThread,在主對話框IDD_SINGLETHREAD_DIALOG添加一個按鈕,ID為IDC_SLEEP_SIX_SECOND,標題為「延時6秒」,添加按鈕的響應函數,代碼如下:
void CSingleThreadDlg::OnSleepSixSecond()
{
Sleep(6000); //延時6秒
}
編譯並運行應用程序,單擊「延時6秒」按鈕,你就會發現在這6秒期間程序就象「死機」一樣,不在響應其它消息。為了更好地處理這種耗時的操作,我們有必要學習——多線程編程。
Ⅷ 多線程編程的原理,請圍繞匯編來說
多線程主要是在80286以及以上的處理器中的功能,最早的32位多線程是80386,看了你另外的帖子,你好象懂點匯編語言,不知道你懂不懂80386匯編,他們的指令形式差不多,區別就在於工作機制和32位.如何你想搞多線程,首先要會386下的匯編,比起8086處理器,它了許多功能,如:分頁機制(虛擬存儲器),多線程等..還有很多功能,至於它多線程的工作機制主要是內存查表的方法,將所有程序的地址段地址和偏移地址放入GDT表和IDT表中,再用時鍾頻率的中斷來不斷讀取這張表到cs:eip寄存器中和將cs:eip內容保存如這樣表,就達到了交換代碼地址,當然這當中還牽涉到很徐徐多多的概念,比如各個寄存器的保存,代碼段的保護,各種控制門,描述符,和cpu內的各種寄存器保存表的地址,這是整整一本書的概念,建議起看揚季文的書叫做8086匯編語言程序設計,上半本書是講8086,是基礎,下半本書是80386是386的工作機制和原理和匯編方法,我在這里就引導你一下
可以說8086和80386是有很大區別的,努力 推薦你一個群 簡單bios和內核研究群,67286087
Ⅸ c++ 多線程編程常用的幾個函數
1、C++多線程也可以使用UNIX C的庫函數,pthread_mutex_t,pthread_create,pthread_cond_t,pthread_detach,pthread_mutex_lock/unlock,等等。在使用多線程的時候,你需要先創建線程,使用pthread_create,你可以使主線程等待子線程使用pthread_join,也可以使線程分離,使用pthread_detach。線程使用中最大的問題就是同步問題,一般使用生產著消費者模型進行處理,使用條件變數pthread_cond_t,pthread_mutex,pthread_cond_wait來實現。
2、常式:
//創建5個線程
#include <pthread.h>
#include <stdlib.h>
void* work_thread(void* arg)
{
//線程執行體
return 0;
}
int main(int argc,char* argv[])
{
int nthread = 5;//創建線程的個數
pthread_t tid;//聲明一個線程ID的變數;
for(int i=0;i<nthread;i++)
{
pthread_create(&tid,NULL,work_thread,NULL);
}
sleep(60);//睡眠一分鍾,你可以看下線程的運行情況,不然主進程會很快節結束了。
}
pthread_create(&tid,NULL,work_thread,NULL);//創建線程的函數,第一個參數返回線程的ID;第二個參數是線程的屬性,一般都置為NULL;第三個參數是線程函數,線程在啟動以後,會自動執行這個函數;第四個參數是線程函數的參數,如果有需要傳遞給線程函數的參數,可以放在這個位置,可以是基礎類型,如果你有不止一個參數想傳進線程函數,可以做一個結構體,然後傳入。
Ⅹ java多線程編程
樓主出現問題有2點:
1. wake() 這個方法也要同步啊,加關鍵字synchronized ;
2. 第一次調用st()方法後,available應該保持不變,這樣才能保證線程b也列印..start,所以加個if判斷一下就ok啦。
public class ABC {
boolean available=false;
String name;
int count=0;
public ABC(String name){
this.name=name;
}
public synchronized void st(){
System.out.println("... start.");
count++;
if(count>1){
available=true;
}
try{
wait();
}catch(Exception e){}
System.out.println("... end.");
}
public synchronized void end(){
System.out.println("... end.");
}
public synchronized void wake() {
notifyAll();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ABC x=new ABC("haha");
TestThread a=new TestThread(x);
TestThread b=new TestThread(x);
C c=new C(x);
(new Thread(a)).start();
(new Thread(b)).start();
(new Thread(c)).start();
}
}
class TestThread implements Runnable{
ABC abc;
public TestThread(ABC abc){
this.abc=abc;
}
public void run(){
if(!abc.available){
abc.st();
}
else abc.end();
}
}
class C implements Runnable{
ABC abc;
public C(ABC abc){
this.abc=abc;
}
public void run(){
try{
Thread.sleep(1000);
// System.out.println("sjlfsj jfsdl j"); //驗證是否執行到這里
}catch(InterruptedException e){};
abc.wake();
}
}