1.Runnable 和 Thread區別
Runnable的實現方式是實現其接口即可
第一步:實現Runnable接口,重寫run方法
public class MyRunnable implements Runnable{ @Override public void run(){ } }
第二步使用MyRunnable:
new Thread(new MyRunnable).start();
Thread的實現方式是繼承其類
public class MyThread extends Thread{ @Override public void run(){
} }
class TestMyThread{
MyThread mythread = new MyThread();
mythread.start();
}
- Runnable接口支持多繼承,但基本上用不到
- Thread實現了Runnable接口並進行了擴展,而Thread和Runnable的實質是實現的關系,不是同類東西,所以Runnable或Thread本身沒有可比性。
多線程原理(
轉載
作者:itbird01
鏈接:https://www.jianshu.com/p/333ce4b3d5b8
來源:簡書):
相當於玩游戲機,只有一個游戲機(cpu),可是有很多人要玩,於是,start是排隊!等CPU選中你就是輪到你,你就run(),當CPU的運行的時間片執行完,這個線程就繼續排隊,等待下一次的run()。
調用start()后,線程會被放到等待隊列,等待CPU調度,並不一定要馬上開始執行,只是將這個線程置於可動行狀態。然后通過JVM,線程Thread會調用run()方法,執行本線程的線程體。
strart()是啟動線程的方法,run()是線程體(內容順序執行),無論是Runnable還是Thread,都是先啟動線程等待Cpu調度,執行線程體。
1.Runnable和Thread相比優點有:
(1)由於Java不允許多繼承,因此實現了Runnable接口可以再繼承其他類,但是Thread明顯不可以
(2)Runnable可以實現多個相同的程序代碼的線程去共享同一個資源,而Thread並不是不可以,而是相比於Runnable來說,不太適合
(1)由於Java不允許多繼承,因此實現了Runnable接口可以再繼承其他類,但是Thread明顯不可以
(2)Runnable可以實現多個相同的程序代碼的線程去共享同一個資源,而Thread並不是不可以,而是相比於Runnable來說,不太適合
public class Test2 { public static void main(String[] args) { MyThread t1 = new MyThread(); new Thread(t1, "線程1").start(); new Thread(t1, "線程2").start(); } public static class MyThread extends Thread { private int total = 10; @Override public void run() { for (int i = 0; i < 10; i++) { synchronized (this) { if (total > 0) { try { Thread.sleep(100); System.out.println(Thread.currentThread().getName() + "賣票---->" + (this.total--)); } catch (InterruptedException e) { e.printStackTrace(); } } } } }
public class Test3 { public static void main(String[] args) { MyRunable t1 = new MyRunable(); new Thread(t1, "線程1").start(); new Thread(t1, "線程2").start();
//當以Thread方式去實現資源共享時,實際上源碼內部是將thread向下轉型為了Runnable,實際上內部依然是以Runnable形式去實現的資源共享 } public static class MyRunable implements Runnable { private int total = 10; @Override public void run() { for (int i = 0; i < 10; i++) { synchronized (this) { if (total > 0) { try { Thread.sleep(100); System.out.println(Thread.currentThread().getName() + "賣票---->" + (this.total--)); } catch (InterruptedException e) { e.printStackTrace(); } } } } } } }
2.Runnable為什么不可以直接run
Runnable其實相對於一個Task,並不具有線程的概念,如果你直接去調用Runnable的run,其實就是相當於直接在主線程中執行了一個函數而已,並未開啟線程去執行
Runnable其實相對於一個Task,並不具有線程的概念,如果你直接去調用Runnable的run,其實就是相當於直接在主線程中執行了一個函數而已,並未開啟線程去執行