① java多線程有幾種實現方法
繼承Thread類來實現多線程:
當我們自定義的類繼承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資源交給下一個線程執行。
② java兩個線程同時調用一個類里的同一個方法,這樣會出現什麼情況有沒有問題
根據不同的情況可能存在的情況有:
③ java中有幾種方法可以實現一個線程
java5以前,有如下兩種:
有兩種實現方法,分別使用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();
從java5開始,還有如下一些線程池創建多線程的方式:
ExecutorService pool = Executors.newFixedThreadPool(3)
for(int i=0;i<10;i++)
{
pool.execute(new Runable(){public void run(){}});
}
Executors.newCachedThreadPool().execute(new Runable(){public void run(){}});
Executors.newSingleThreadExecutor().execute(new Runable(){public void run(){}});
④ JAVA多線程有哪幾種實現方式
JAVA多線程實現方式主要有三種:繼承Thread類、實現Runnable介面、使用ExecutorService、Callable、Future實現有返回結果的多線程。其中前兩種方式線程執行完後都沒有返回值,只有最後一種是帶返回值的。
1、繼承Thread類實現多線程
繼承Thread類的方法盡管被我列為一種多線程實現方式,但Thread本質上也是實現了Runnable介面的一個實例,它代表一個線程的實例,並且,啟動線程的唯一方法就是通過Thread類的start()實例方法。start()方法是一個native方法,它將啟動一個新線程,並執行run()方法。這種方式實現多線程很簡單,通過自己的類直接extend Thread,並復寫run()方法,就可以啟動新線程並執行自己定義的run()方法。例如:
[java]view plain
{
publicvoidrun(){
System.out.println("MyThread.run()");
}
}
[java]view plain
MyThreadmyThread1=newMyThread();
MyThreadmyThread2=newMyThread();
myThread1.start();
myThread2.start();
[java]view plain
{
publicvoidrun(){
System.out.println("MyThread.run()");
}
}
[java]view plain
MyThreadmyThread=newMyThread();
Threadthread=newThread(myThread);
thread.start();
[java]view plain
publicvoidrun(){
if(target!=null){
target.run();
}
}
⑤ 在Java 中多線程的實現方法有哪些,如何使用
1、 認識Thread和Runnable
Java中實現多線程有兩種途徑:繼承Thread類或者實現Runnable介面。Runnable是介面,建議用介面的方式生成線程,因為介面可以實現多繼承,況且Runnable只有一個run方法,很適合繼承。在使用Thread的時候只需繼承Thread,並且new一個實例出來,調用start()方法即可以啟動一個線程。
Thread Test = new Thread();
Test.start();
在使用Runnable的時候需要先new一個實現Runnable的實例,之後啟動Thread即可。
Test impelements Runnable;
Test t = new Test();
Thread test = new Thread(t);
test.start();
總結:Thread和Runnable是實現java多線程的2種方式,runable是介面,thread是類,建議使用runable實現java多線程,不管如何,最終都需要通過thread.start()來使線程處於可運行狀態。
2、 認識Thread的start和run
1) start:
用start方法來啟動線程,真正實現了多線程運行,這時無需等待run方法體代碼執行完畢而直接繼續執行下面的代碼。通過調用Thread類的start()方法來啟動一個線程,這時此線程處於就緒(可運行)狀態,並沒有運行,一旦得到spu時間片,就開始執行run()方法,這里方法run()稱為線程體,它包含了要執行的這個線程的內容,Run方法運行結束,此線程隨即終止。
2) run:
run()方法只是類的一個普通方法而已,如果直接調用Run方法,程序中依然只有主線程這一個線程,其程序執行路徑還是只有一條,還是要順序執行,還是要等待run方法體執行完畢後才可繼續執行下面的代碼,這樣就沒有達到寫線程的目的。
總結:調用start方法方可啟動線程,而run方法只是thread的一個普通方法調用,還是在主線程里執行。
3、 線程狀態說明
線程狀態從大的方面來說,可歸結為:初始狀態、可運行狀態、不可運行狀態和消亡狀態,具體可細分為上圖所示7個狀態,說明如下:
1) 線程的實現有兩種方式,一是繼承Thread類,二是實現Runnable介面,但不管怎樣,當我們new了thread實例後,線程就進入了初始狀態;
2) 當該對象調用了start()方法,就進入可運行狀態;
3) 進入可運行狀態後,當該對象被操作系統選中,獲得CPU時間片就會進入運行狀態;
4) 進入運行狀態後case就比較多,大致有如下情形:
·run()方法或main()方法結束後,線程就進入終止狀態;
·當線程調用了自身的sleep()方法或其他線程的join()方法,就會進入阻塞狀態(該狀態既停止當前線程,但並不釋放所佔有的資源)。當sleep()結束或join()結束後,該線程進入可運行狀態,繼續等待OS分配時間片;
·當線程剛進入可運行狀態(注意,還沒運行),發現將要調用的資源被鎖牢(synchroniza,lock),將會立即進入鎖池狀態,等待獲取鎖標記(這時的鎖池裡也許已經有了其他線程在等待獲取鎖標記,這時它們處於隊列狀態,既先到先得),一旦線程獲得鎖標記後,就轉入可運行狀態,等待OS分配CPU時間片;
·當線程調用wait()方法後會進入等待隊列(進入這個狀態會釋放所佔有的所有資源,與阻塞狀態不同),進入這個狀態後,是不能自動喚醒的,必須依靠其他線程調用notify()或notifyAll()方法才能被喚醒(由於notify()只是喚醒一個線程,但我們由不能確定具體喚醒的是哪一個線程,也許我們需要喚醒的線程不能夠被喚醒,因此在實際使用時,一般都用notifyAll()方法,喚醒有所線程),線程被喚醒後會進入鎖池,等待獲取鎖標記。
·當線程調用stop方法,即可使線程進入消亡狀態,但是由於stop方法是不安全的,不鼓勵使用,大家可以通過run方法里的條件變通實現線程的stop。
⑥ java 中 如何讓一個方法內最多隻能有兩個線程訪問
信號量Semaphore。下面代碼里,一個semp的信號量初始值為5,.acquire()一次-1,.release()一次+1,如果信號量值為0的時候.acquire()就會阻塞線程,直到別的線程.release()。下面的實例是允許最多5個線程同時訪問.acquire()和.release()之間的代碼,你設置初始值為2就可以了。
publicclassSemaphoreTest{
publicstaticvoidmain(String[]args){
//線程池
ExecutorServiceexec=Executors.newCachedThreadPool();
//只能5個線程同時訪問
finalSemaphoresemp=newSemaphore(5);
//模擬20個客戶端訪問
for(intindex=0;index<20;index++){
finalintNO=index;
Runnablerun=newRunnable(){
publicvoidrun(){
try{
//獲取許可
semp.acquire();
System.out.println("Accessing:"+NO);
Thread.sleep((long)(Math.random()*10000));
//訪問完後,釋放,如果屏蔽下面的語句,則在控制台只能列印5條記錄,之後線程一直阻塞
semp.release();
}catch(InterruptedExceptione){
}
}
};
exec.execute(run);
}
//退出線程池
exec.shutdown();
}
}
給你個鏈接看看
http://blog.csdn.net/shihuacai/article/details/8856526
⑦ java中實現多線程的方法有幾種以及如何實現多線程
java中實現多線程的方法有兩種,1:繼承Tread類;2:實現Runable介面
1、
{
//重寫run()方法
publicvoidrun(){
//多線程要做的事
}
publicstaticvoidmain(Stringargs[]){
MyThreadm1=newMyThread();
MyThreadm2=newMyThread();
m1.start();
m2.start();
}
}
2、
{
//實現run()方法
publicvoidrun(){
//多線程要做的事
}
publicstaticvoidmain(Stringargs[]){
NThreadnt=newNThread();
newThread(nt,"nt1_name").start();
newThread(nt,"nt2_name").start();
}
}