⑴ 1. 寫出用Java編寫多線程程序的兩種常用方法
1、繼承Thread,然後生成對象
2、用類A實現runable介面,然後用你實現runnable的類A,生成Thread對象 Thread(A對象);
API 上說明如下:
創建新執行線程有兩種方法。一種方法是將類聲明為 Thread 的子類。該子類應重寫 Thread 類的
run 方法。接下來可以分配並啟動該子類的實例。例如,計算大於某一規定值的質數的線程可以寫成:
classPrimeThreadextendsThread{
longminPrime;
PrimeThread(longminPrime){
this.minPrime=minPrime;
}
publicvoidrun(){
//
...
}
}
然後,下列代碼會創建並啟動一個線程:
PrimeThreadp=newPrimeThread(143);
p.start();
創建線程的另一種方法是聲明實現 Runnable 介面的類。該類然後實現 run
方法。然後可以分配該類的實例,在創建 Thread 時作為一個參數來傳遞並啟動。採用這種風格的同一個例子如下所示:
implementsRunnable{
longminPrime;
PrimeRun(longminPrime){
this.minPrime=minPrime;
}
publicvoidrun(){
//
...
}
}
然後,下列代碼會創建並啟動一個線程:
rimeRunp=newPrimeRun(143);
newThread(p).start();
⑵ java 線程 有幾種創建方法啊 最常用的是哪種啊
繼承Thread類和實現Runnable介面
第二種常用。因為如果繼承自Thread類的話,java是單繼承機制所以就沒有辦法再繼承其他類了。而實現Runnable介面則還可以再繼承其他的類。
就像你設計一個程序,如果不用線程,那麼它就是順序執行。但是有些額外的操作不能和主程序一起執行,就舉個簡單的例子吧,一個網頁上,上面一個顯示時間,而且時間是不斷的變化的,而你在下面注冊你的賬號,那這2個操作按順序執行那麼有一個就不能執行了,而時間是一直變化的,所有就要開啟一個線程,讓那個時間不斷的變化,而不影響到你去注冊賬號。
⑷ 線程同步常用方式與區別
進程中線程同步的四種常用方式:
1、 臨界區(CCriticalSection)
當多個線程訪問一個獨占性共享資源時,可以使用臨界區對象。擁有臨界區的線程可以訪問被保護起來的資源或代碼段,其他線程若想訪問,則被掛起,直到擁有臨界區的線程放棄臨界區為止。具體應用方式:
1、 定義臨界區對象CcriticalSection g_CriticalSection;
2、 在訪問共享資源(代碼或變數)之前,先獲得臨界區對象,g_CriticalSection.Lock();
3、 訪問共享資源後,則放棄臨界區對象,g_CriticalSection.Unlock();
2、 事件(CEvent)
事件機制,則允許一個線程在處理完一個任務後,主動喚醒另外一個線程執行任務。比如在某些網路應用程序中,一個線程如A負責偵聽通信埠,另外一個線程B負責更新用戶數據,利用事件機制,則線程A可以通知線程B何時更新用戶數據。每個Cevent對象可以有兩種狀態:有信號狀態和無信號狀態。Cevent類對象有兩種類型:人工事件和自動事件。
自動事件對象,在被至少一個線程釋放後自動返回到無信號狀態;
人工事件對象,獲得信號後,釋放可利用線程,但直到調用成員函數ReSet()才將其設置為無信號狀態。在創建Cevent對象時,默認創建的是自動事件。
1、1234CEvent(BOOL bInitiallyOwn=FALSE, BOOL bManualReset=FALSE, LPCTSTR lpszName=NULL, LPSECURITY_ATTRIBUTES lpsaAttribute=NULL);
bInitiallyOwn:指定事件對象初始化狀態,TRUE為有信號,FALSE為無信號;
bManualReset:指定要創建的事件是屬於人工事件還是自動事件。TRUE為人工事件,FALSE為自動事件;
後兩個參數一般設為NULL,在此不作過多說明。
2、BOOL CEvent::SetEvent();
將Cevent類對象的狀態設置為有信號狀態。如果事件是人工事件,則Cevent類對象保持為有信號狀態,直到調用成員函數ResetEvent()將其重新設為無信號狀態時為止。如果為自動事件,則在SetEvent()後將事件設置為有信號狀態,由系統自動重置為無信號狀態。
3、BOOL CEvent::ResetEvent();
將事件的狀態設置為無信號狀態,並保持該狀態直至SetEvent()被調用為止。由於自動事件是由系統自動重置,故自動事件不需要調用該函數。
一般通過調用WaitForSingleObject()函數來監視事件狀態。
3、 互斥量(CMutex)
互斥對象和臨界區對象非常相似,只是其允許在進程間使用,而臨界區只限制與同一進程的各個線程之間使用,
但是更節省資源,更有效率。
4、 信號量(CSemphore)
當需要一個計數器來限制可以使用某共享資源的線程數目時,可以使用「信號量」對象。CSemaphore類對象保存了對當前訪問某一個指定資源的線程的計數值,該計數值是當前還可以使用該資源的線程數目。如果這個計數達到了零,則所有對這個CSemaphore類對象所控制的資源的訪問嘗試都被放入到一個隊列中等待,直到超時或計數值不為零為止。
CSemaphore(
LONG lInitialCount = 1,
LONG lMaxCount = 1,
LPCTSTR pstrName = NULL,
LPSECURITY_ATTRIBUTES lpsaAttributes = NULL
);
lInitialCount:信號量對象的初始計數值,即可訪問線程數目的初始值;
lMaxCount:信號量對象計數值的最大值,該參數決定了同一時刻可訪問由信號量保護的資源的線程最大數目;
後兩個參數在同一進程中使用一般為NULL,不作過多討論;
一般是將當前可用資源計數設置為最大資源計數,每增加一個線程對共享資源的訪問,當前可用資源計數就減1,只要當前可用資源計數大於0,就可以發出信號量信號。如果為0,則放入一個隊列中等待。線程在處理完共享資源後,應在離開的同時通過ReleaseSemaphore()函數將當前可用資源數加1。
⑸ java 中使用線程的方法到底有哪些
都是通過new Thread().start()開啟線程,一般有兩種方式:1是繼承自Thread類,2是實現Runnable介面,第二種方式更加靈活,Java不支持多繼承,但是支持多實現。求採納
⑹ thread類的方法是什麼
Thread類的常用方法:
String getName()返回該線程的名稱。
void setName(String name)改變線程名稱,使之與參數name相同。
int getPriority()返回線程的優先順序。
void setPriority(int newPriority)更改線程的優先順序。
boolean isDaemon()測試該線程是否為守護線程。
void setDaemon(boolean on)將該線程標記為守護線程或用戶線程。
void interrupt()中斷線程。
static void yield()暫停當前正在執行的線程對象,並執行其他線程。
void join()等待該線程終止。
void run()
void start()
從Object類繼承來的方法void notify() void wait()
⑺ 多線程實現的幾種常用的方法
有三種:
(1)繼承Thread類,重寫run函數
創建:
class xx extends Thread{
public void run(){
Thread.sleep(1000) //線程休眠1000毫秒,sleep使線程進入Block狀態,並釋放資源
}}
開啟線程:
對象.start() //啟動線程,run函數運行
(2)實現Runnable介面,重寫run函數
開啟線程:
Thread t = new Thread(對象) //創建線程對象
t.start()
(3)實現Callable介面,重寫call函數
Callable是類似於Runnable的介面,實現Callable介面的類和實現Runnable的類都是可被其它線程執行的任務。
Callable和Runnable有幾點不同:
①Callable規定的方法是call(),而Runnable規定的方法是run().
②Callable的任務執行後可返回值,而Runnable的任務是不能返回值的
③call()方法可拋出異常,而run()方法是不能拋出異常的。
④運行Callable任務可拿到一個Future對象,Future表示非同步計算的結果。它提供了檢查計算是否完成的方法,以等
待計算的完成,並檢索計算的結果.通過Future對象可了解任務執行情況,可取消任務的執行,還可獲取任務執行的結果
⑻ 創建線程有幾種不同方式,最常用那種 Java面試題
有三種方式可以用來創建線程:
繼承Thread類
實現Runnable介面
應用程序可以使用Executor框架來創建線程池
實現Runnable介面這種方式更受歡迎,因為這不需要繼承Thread類。在應用設計中已經繼承了別的對象的情況下,這需要多繼承(而Java不支持多繼承),只能實現介面。同時,線程池也是非常高效的,很容易實現和使用。
⑼ 線程間通信方式有哪些
多線程通信的方法主要有以下三種:
1.全局變數
進程中的線程間內存共享,這是比較常用的通信方式和交互方式。
註:定義全局變數時最好使用volatile來定義,以防編譯器對此變數進行優化。
2.Message消息機制
常用的Message通信的介面主要有兩個:PostMessage和PostThreadMessage,
PostMessage為線程向主窗口發送消息。而PostThreadMessage是任意兩個線程之間的通信介面。
2.1.PostMessage()
函數原型:
B00L PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
參數:
hWnd:其窗口程序接收消息的窗口的句柄。可取有特定含義的兩個值:
HWND.BROADCAST:消息被寄送到系統的所有頂層窗口,包括無效或不可見的非自身擁有的窗口、被覆蓋的窗口
和彈出式窗口。消息不被寄送到子窗口。
NULL:此函數的操作和調用參數dwThread設置為當前線程的標識符PostThreadMessage函數一樣。
Msg:指定被寄送的消息。
wParam:指定附加的消息特定的信息。
IParam:指定附加的消息特定的信息。
返回值:如果函數調用成功,返回非零值:如果函數調用失敗,返回值是零。
MS還提供了SendMessage方法進行消息間通訊,SendMessage(),他和PostMessage的區別是:
SendMessage是同步的,而PostMessage是非同步的。SendMessage必須等發送的消息執行之後,才返回。
2.2.PostThreadMessage()
PostThreadMessage方法可以將消息發送到指定線程。
函數原型:BOOL PostThreadMessage(DWORD idThread,UINT Msg,WPARAM wParam, LPARAM lParam);
參數除了ThreadId之外,基本和PostMessage相同。
目標線程通過GetMessage()方法來接受消息。
註:使用這個方法時,目標線程必須已經有自己的消息隊列。否則會返回ERROR_INVALID_THREAD_ID錯誤。可以用
PeekMessage()給線程創建消息隊列。
3.CEvent對象
CEvent為MFC中的一個對象,可以通過對CEvent的觸發狀態進行改變,從而實現線程間的通信和同步。
⑽ java多線程方法有哪些
java實現線程常用到的方法有三種,供參考:
/**
*方法一:繼承Thread類
*
*@authorqd
*
*/
{
@Override
publicvoidrun(){
System.out.println("run方法裡面編寫業務代碼");
}
publicstaticvoidmain(String[]args){
MyThreadmyThread=newMyThread();
//調用start方法啟動線程
myThread.start();
MyThread1myThread1=newMyThread1();
Threadthread=newThread(myThread1);
//調用start方法啟動線程
thread.start();
}
}
/**
*方法二:實現Runnable介面
*
*@authorqd
*
*/
{
@Override
publicvoidrun(){
System.out.println("run方法裡面編寫業務代碼");
}
}
/**
*方法三:實現Callable<T>介面優點:可以傳參數,有返回值類型
*
*@authorqd
*
*/
<Integer>{
@Override
publicIntegercall()throwsException{
returnnull;
}
}