首頁  >  文章  >  Java  >  Java中的Runnable和Thread的差別有哪些?

Java中的Runnable和Thread的差別有哪些?

WBOY
WBOY轉載
2023-05-07 17:19:08939瀏覽

在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.demo.dff;  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--);  }  }  }  };

下面通過三個線程對象,同時賣票:

package org.demo.dff;  public class ThreadTicket {  public static void main(String[] args) {  MyThread mt1=new MyThread();  MyThread mt2=new MyThread();  MyThread mt3=new MyThread();  mt1.start();//每个线程都各卖了10张,共卖了30张票  mt2.start();//但实际只有10张票,每个线程都卖自己的票  mt3.start();//没有达到资源共享  }  }

如果用Runnable就可以實現資源共享,下面看例子:

package org.demo.runnable;  class MyThread implements Runnable{  private int ticket=10;  public void run(){  for(int i=0;i<20;i++){  if(this.ticket>0){  System.out.println("卖票:ticket"+this.ticket--);  }  }  }  }  package org.demo.runnable;  public class RunnableTicket {  public static void main(String[] args) {  MyThread mt=new MyThread();  new Thread(mt).start();//同一个mt,但是在Thread中就不可以,如果用同一  new Thread(mt).start();//个实例化对象mt,就会出现异常  new Thread(mt).start();  }  };

雖然現在程式中有三個線程,但是一共賣了10張票,也就是說使用Runnable實作多執行緒可以達到資源共享目的。

Runnable介面與Thread之間的連結:

public class Thread extends Object implements Runnable

發現Thread類別也是Runnable介面的子類別。

以上是Java中的Runnable和Thread的差別有哪些?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除