⑴ 創建多線程有幾種方法
1、通過繼承Thread類創建線程
(1).首先定義一個類去繼承Thread父類,重寫父類中的run()方法。在run()方法中加入具體的任務代碼或處理邏輯。
(2).直接創建一個ThreadTest類的對象,也可以利用多態性,變數聲明為父類的類型。
(3).調用start方法,線程啟動,隱含的調用run()方法。
[java]view plain
{
publicvoidrun(){
for(inti=0;i<=10;i++){
System.out.println(i);
}
}
publicstaticvoidmain(String[]args){
ThreadTestthread1=newThreadTest();
ThreadTestthread2=newThreadTest();
thread1.start();
thread2.start();
}
}
2、通過實現Runnable介面創建線程
(1).定義一個類實現Runnable介面,重寫介面中的run()方法。在run()方法中加入具體的任務代碼或處理邏輯。
(2).創建Runnable介面實現類的對象。
(3).創建一個ThreadTest類的對象,需要封裝前面Runnable介面實現類的對象。(介面可以實現多繼承)
(4).調用Thread對象的start()方法,啟動線程
[java]view plain
{
@Override
publicvoidrun(){
for(inti=0;i<=10;i++){
System.out.println(i);
}
}
publicstaticvoidmain(String[]args){
ThreadTestthreadTest=newThreadTest();
Threadtheard=newThread(threadTest);
theard.start();
}
}
3.通過Callable和Future創建線程
(1)創建Callable介面的實現類,並實現call()方法,該call()方法將作為線程執行體,並且有返回值。
(2)創建Callable實現類的實例,使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了該Callable對象的call()方法的返回值。
(3)使用FutureTask對象作為Thread對象的target創建並啟動新線程。
(4)調用FutureTask對象的get()方法來獲得子線程執行結束後的返回值
[java]view plain
<Integer>{
@Override
publicIntegercall()throwsException{
intcount=0;
for(inti=0;i<=10;i++){
count=count+i;
}
returncount;
}
publicstaticvoidmain(String[]args)throwsInterruptedException,ExecutionException{
ThreadTesttest=newThreadTest();
FutureTask<Integer>thread=newFutureTask<>(test);
newThread(thread,"有返回值的線程").start();
System.out.println(thread.get());
}
}
使用實現Runnable介面方式創建線程可以共享同一個目標對象(TreadDemo1 tt=new TreadDemo1();),實現了多個相同線程處理同一份資源。
然後再看一段來自JDK的解釋:
TheRunnableinterface should be implemented by any class whose instances are intended to be executed by a thread. The class must define a method of no arguments calledrun.
This interface is designed to provide a common protocol for objects that wish to execute code while they are active. For example,Runnableis implemented by classThread. Being active simply means that a thread has been started and has not yet been stopped.
In addition,Runnableprovides the means for a class to be active while not subclassingThread. A class that implementsRunnablecan run without subclassingThreadby instantiating aThreadinstance and passing itself in as the target. In most cases, theRunnableinterface should be used if you are only planning to override therun()method and no otherThreadmethods. This is important because classes should not be subclassed unless the programmer intends on modifying or enhancing the fundamental behavior of the class.
採用實現Runnable、Callable介面的方式創見多線程時,優勢是:
線程類只是實現了Runnable介面或Callable介面,還可以繼承其他類。
在這種方式下,多個線程可以共享同一個target對象,所以非常適合多個相同線程來處理同一份資源的情況,從而可以將CPU、代碼和數據分開,形成清晰的模型,較好地體現了面向對象的思想。
劣勢是:
採用繼承Thread類方式:
(1)優點:編寫簡單,如果需要訪問當前線程,無需使用Thread.currentThread()方法,直接使用this,即可獲得當前線程。
(2)缺點:因為線程類已經繼承了Thread類,所以不能再繼承其他的父類。
採用實現Runnable介面方式:
(1)優點:線程類只是實現了Runable介面,還可以繼承其他的類。在這種方式下,可以多個線程共享同一個目標對象,所以非常適合多個相同線程來處理同一份資源的情況,從而可以將CPU代碼和數據分開,形成清晰的模型,較好地體現了面向對象的思想。
(2)缺點:編程稍微復雜,如果需要訪問當前線程,必須使用Thread.currentThread()方法。
⑵ java中實現多線程的方法有幾種以及如何實現多線程
繼承Thread類,然後重寫run方法
實現Runnable介面,實現run方法
這是最常用的實現多線程的方式
⑶ 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;
}
}
⑷ 多線程有幾種實現方法
在java5以前實現多線程有兩種方法(繼承Thread類和實現Runnable介面)
它們分別為:
使用new Thread()和new Thread(Runnable)形式
第一種直接調用thread的run方法,所以,往往使用Thread子類,即new SubThread()。
第二種調用
Runnable的run方法。
第一種:
new Thread(){}.start();這表示調用Thread子類對象的run方法,new Thread(){}表示一個Thread的匿名子類的實例對象,子類加上run方法後的代碼如下:
new Thread(){
public void run(){
}
}.start();
第二種:
new Thread(
new Runnable(){}
).start();
這表示調用Thread對象接受的Runnable對象的run方法,new Runnable(){}表示一個Runnable的匿名子類的實例對象,
runnable的子類加上run方法後的代碼如下:
new Thread(new Runnable(){
public void run(){
}
}
).start();
⑸ 多線程的幾種實現方法詳解
首先線程都是由Thread類來創建的,線程任務實現有2中方式
繼承Thread類
實現Runnable類
還有一些線程的執行類,可以看看
⑹ 實現多線程都有哪幾種方法
1:UI線程。這個線程是操作系統自動創建的,你畫了個winform,那麼程序一啟動,自然有了這么個線程。值得注意的是,你添加一個Timer控制項,現實的多線程,實際上,依然在UI線程里。只是定時被Timer奪去控制權而已,本質上依然是單線程。另一個線索也可以論證:本來非UI線程想更新UI界面,是需要利用delegate,involk等來實現的,但是在timer控制項的線程里,是不需要的。2:Threadthread=newThread(obj.functionName);thread.start();這樣自定義的線程是真正的多線程,它的使用也是最靈活的。不像Timer線程,精確度只有50ms。值得注意的是:如果需要啟動的線程函數是帶輸入參數的,怎麼?有兩個法:A:你不是啟動obj對象里的函數嗎?在thread.start();之前,你先添加這句話MyObjectobj=newMyObject(inta,intb);這樣,obj.functionName函數里可以直接使用a和b了。還有個方法,就是利用委託封裝函數,然後thread.start(參數);具體代碼如下:[ComVisibleAttribute(false)](Objectobj)//這個Thread類的構造方法的定義如下:publicThread(ParameterizedThreadStartstart);(Objectobj){Console.WriteLine(obj);}staticvoidMain(string[]args){Threadthread=newThread(myStaticParamThreadMethod);thread.Start("通過委託的參數傳值");}3:利用threadpool線程池技術。threadpool的主要原理是池裡面的線程不會完成一個任務就消亡,而是會繼續執行其他的任務,這減少了線程的消亡和生成的代價。主要是ThreadPool.QueueUserWorkItem()和ThreadPool.RegisterWaitForSingleObject(···)兩個靜態函數。具體如下:QueueUserWorkItem的使用:staticvoidThreadProc(ObjectstateInfo){Console.WriteLine("Hellofromthethreadpool.");}Main函數里ThreadPool.QueueUserWorkItem(newWaitCallback(ThreadProc));即可。(注意WaitCallback系統委託),它的功能就像第2種方法里提到的newthread。那麼RegisterWaitForSingleObject是干什麼的呢?這個方法的做用是向線程池添加一個可以定時執行的方法。有點像第一種方法里提到的timer線程,卻不屬於UI線程。具體的使用如下:AutoResetEventwait=newAutoResetEvent(false);objectstate=newobject();ThreadPool.RegisterWaitForSingleObject(wait,newWaitOrTimerCallback(test),state,5000,false);//5000是間隔調用的時間,也就是wait變數卡住的timeout時間(我覺得內部是這樣實現的)wait.Set();//如果有set這句話,那麼第一次執行不用等5秒,則直接執行目標函數,否則沒這句話,第一次執行要等5秒的。還有一個要注意:我平常使用的是ManualResetEvent,但在threadpool里,首先要選的是AutoResetEvent,因為AutoResetEvent能自動reset,所以下一次間隔來了,又要重新等待5秒鍾,達到定時器的目的。如果是ManualResetEvent,要麼一次執行不了(初始值為false),要麼不間斷的玩命執行。ManualResetEvent和AutoResetEvent的另一個重要區別是前者能一次喚醒多個線程,而後者一次只能喚醒一個線程。其實RegisterWaitForSingleObject函數的使用有點想我封裝好的MyTimer類的實現了:我裡面的while死循環里用了個wait.waitone(2000,false);即可。對了,說到這里,RegisterWaitForSingleObject函數實現的定時器,如果手動停止呢?這要用到Unregister函數:RegisteredWaitHandlerw=ThreadPool.RegisterWaitForSingleObject(wait,newWaitOrTimerCallback(test),state,3000,false);rw.Unregister(wait);嗯討論了這么多線程的東西,乾脆再說一個小點:Thread.IsBackground=true的時候,指示該線程為後台線程。後台線程將會隨著主線程的退出而退出