Thread 和runnable的區別
在java中可有兩種方式實現多執行緒,一種是繼承Thread類,一種是實現Runnable介面;Thread類是在java.lang包中定義的。一個類只要繼承了Thread類同時覆寫了本類中的run()方法就可以實現多執行緒操作了,但是一個類只能繼承一個父類,這是此方法的侷限。
下面看例子:
package org.thread.demo;
class MyThread extends Thread{
private String name;
public MyThread(String name) {
super();
this.name = name;
}
public void run(){
for(int i=0;i<10;i++){
System.out.println("執行緒開始:"+this.name+",i="+i);
}
}
}
package org.thread.demo;
public class ThreadDemo01 {
public static void main(String[] args) {
MyThread mt1=new MyThread("執行緒a");
MyThread mt2=new MyThread("執行緒b");
mt1.run();
mt2.run();
}
}
但是,此時結果很有規律,先第一個物件執行,然後第二個物件執行,並沒有相互執行。在JDK的文件中可以發現,一旦呼叫start()方法,則會通過JVM找到run()方法。下面啟動start()方法啟動執行緒:
package org.thread.demo;
public class ThreadDemo01 {
public static void main(String[] args) {
MyThread mt1=new MyThread("執行緒a");
MyThread mt2=new MyThread("執行緒b");
mt1.start();
mt2.start();
}
};
這樣程式可以正常完成互動式執行。那麼為啥非要使用start();方法啟動多執行緒呢?
在JDK的安裝路徑下,src.zip是全部的java源程式,通過此程式碼找到Thread中的start()方法的定義,可以發現此方法中使用了private native void start0();其中native關鍵字表示可以呼叫作業系統的底層函式,那麼這樣的技術成為JNI技術(java Native Interface)
Runnable介面
在實際開發中一個多執行緒的操作很少使用Thread類,而是通過Runnable介面完成。
public interface Runnable{
public void run();
}
例子:
package org.runnable.demo;
class MyThread implements Runnable{
private String name;
public MyThread(String name) {
this.name = name;
}
public void run(){
for(int i=0;i<100;i++){
System.out.println("執行緒開始:"+this.name+",i="+i);
}
}
};
但是在使用Runnable定義的子類中沒有start()方法,只有Thread類中才有。此時觀察Thread類,有一個構造方法:public Thread(Runnable targer)此構造方法接受Runnable的子類例項,也就是說可以通過Thread類來啟動Runnable實現的多執行緒。(start()可以協調系統的資源):
package org.runnable.demo;
import org.runnable.demo.MyThread;
public class ThreadDemo01 {
public static void main(String[] args) {
MyThread mt1=new MyThread("執行緒a");
MyThread mt2=new MyThread("執行緒b");
new Thread(mt1).start();
new Thread(mt2).start();
}
}
兩種實現方式的區別和聯絡:
在程式開發中只要是多執行緒肯定永遠以實現Runnable介面為主,因為實現Runnable介面相比繼承Thread類有如下好處:
- 避免點繼承的侷限,一個類可以繼承多個介面。
- 適合於資源的共享
以賣票程式為例,通過Thread類完成:
package org.thread;
public class MyThread extends Thread{
private int ticket=10;
public void run(){
for(int i=0;i<20;i--){
if(this.ticket>0){
System.out.println("買票:ticket="+this.ticket--+"======"+Thread.currentThread().getName());
}
}
}
}
下面通過兩個執行緒物件,同時賣票:
public class MyThreadTest{
public static void main(String []args){
MyThread thread01=new MyThread();
MyThread thread02=new MyThread();
thread01.start();//每個執行緒賣了10張票,共賣了20張票
thread02.start();//但實際只有10張票,每個執行緒都賣自己的票 //沒有達到資源共享
}
}
執行結果
買票:ticket=10======Thread-0
買票:ticket=10======Thread-1
買票:ticket=9======Thread-1
買票:ticket=8======Thread-1
買票:ticket=7======Thread-1
買票:ticket=6======Thread-1
買票:ticket=9======Thread-0
買票:ticket=5======Thread-1
買票:ticket=4======Thread-1....
如果用Runnable就可以實現資源共享,下面看例子:
package org.thread;
public class MyThread02 implements Runnable{
private int ticket=10;
public void run(){
for(int i=0;i<20;i++){
if(ticket>0){
System.out.println("賣票:ticket ="+ticket--+"===="+Thread.currentThread().getName());
}
}
}
}
package org.thread;
public class MyThreadTest02 {
public static void main(String []args){
MyThread02 thread02=new MyThread02();
Thread thread01=new Thread(thread02);
Thread thread02s=new Thread(thread02);
thread01.start();//兩個執行緒一共賣10張票
thread02s.start();
}
}
執行結果
賣票:ticket =10====Thread-0
賣票:ticket =9====Thread-1
賣票:ticket =8====Thread-0
賣票:ticket =7====Thread-1
賣票:ticket =6====Thread-0
賣票:ticket =5====Thread-1
賣票:ticket =4====Thread-0
賣票:ticket =3====Thread-1
賣票:ticket =2====Thread-0
賣票:ticket =1====Thread-1
雖然現在程式中有2個執行緒,但是一共賣了10張票,也就是說使用Runnable實現多執行緒可以達到資源共享目的。
相關文章
- Thread和Runnable的區別thread
- Java中Runnable和Thread的區別Javathread
- Java 中Thread 和Runnable的區別Javathread
- java執行緒系列---Runnable和Thread的區別Java執行緒thread
- 使用Thread類和Runnable介面實現多執行緒的區別thread執行緒
- Android中Handler Runnable與Thread的區別詳解Androidthread
- 大話Android多執行緒(一) Thread和Runnable的聯絡和區別Android執行緒thread
- Handler post(Runnable runnable)和sendMessage(Message msg)的區別比較
- 併發-2-Thread和Runnable的APIthreadAPI
- Java中Thread 和Runnable 深入理解Javathread
- Thread是如何處理Runnable的thread
- 轉android-Service和Thread的區別Androidthread
- Task.Delay 和 Thread.Sleep 的區別thread
- Thread(Runnable xxx)中的問題thread
- Thread的run()與start()的區別thread
- 【胡思亂想】命令模式 與 Thread Runnable模式thread
- Thread的wait和notify是指的是 Runnable物件而不是 Thread物件,切記,否則喚醒失效threadAI物件
- Hystrix semaphore和thread隔離策略的區別及配置參thread
- JAVA多執行緒Thread VS Runnable詳解Java執行緒thread
- Thread.currentThread().getName() 和 this.getName()區別詳解thread
- java面試題之Thread的run()和start()方法有什麼區別Java面試題thread
- `std::packaged_task`、`std::thread` 和 `std::async` 的區別與聯絡Packagethread
- (十三) 說一下runnable 和 callable 有什麼區別?Future是什麼?
- ../和./和/的區別
- 如何區分 Connection、Thread和SessionthreadSession
- 和 的區別
- as 和 with的區別
- ||和??的區別
- /*和/**的區別
- Java_Thread類的sleep()與SystemClock類的sleep()的區別Javathread
- LinkedList和ArrayList的區別、Vector和ArrayList的區別
- http和https的區別/get和post的區別HTTP
- java多執行緒程式設計,Thread,Runnable,Future相關知識Java執行緒程式設計thread
- ./ 和sh 的區別
- JQuery this和$(this)的區別jQuery
- jquery $(this) 和this的區別jQuery
- T和?的區別
- ++a和a++的區別