Java中Runnable和Thread的區別
概述
Runnable 是介面。
Thread 是類,且實現了Runnable介面。
Thread部分原始碼
public class Thread
implements Runnable
{
private static class Caches
{
static final ConcurrentMap subclassAudits = new ConcurrentHashMap();
static final ReferenceQueue subclassAuditsQueue = new ReferenceQueue();
在使用Runnable定義的子類中沒有start()方法,只有Thread類中才有。
public interface Runnable
{
public abstract void run();
}
Thread類,有一個構造方法:public Thread(Runnable targer)
public Thread(Runnable runnable) { daemon = false; stillborn = false; threadLocals = null; inheritableThreadLocals = null; threadStatus = 0; blockerLock = new Object(); init(null, runnable, (new StringBuilder()).append("Thread-").append(nextThreadNum()).toString(), 0L); }
此構造方法接受Runnable的子類例項,也就是說可以通過Thread類來啟動Runnable實現的多執行緒。
使用情況
在程式開發中只要是多執行緒肯定永遠以實現Runnable介面為主。
實現Runnable介面相比繼承Thread類有如下好處:
1、避免繼承的侷限,一個類可以繼承多個介面。
2、適合於資源的共享。
例項
以賣票為例,總共只有10張動車票了,全國3個視窗在賣。
繼承Thread類的方法
package multithreading; public class MyThreadWithExtends extends Thread { private int tickets = 10; @Override public void run() { for (int i = 0; i <= 100; i++) { if(tickets>0){ System.out.println(Thread.currentThread().getName()+"--賣出票:" + tickets--); } } } public static void main(String[] args) { MyThreadWithExtends thread1 = new MyThreadWithExtends(); MyThreadWithExtends thread2 = new MyThreadWithExtends(); MyThreadWithExtends thread3 = new MyThreadWithExtends(); thread1.start(); thread2.start(); thread3.start(); //每個執行緒都獨立,不共享資源,每個執行緒都賣出了10張票,總共賣出了30張。如果真賣票,就有問題了。 } }
執行結果:
Thread-0--賣出票:10
Thread-2--賣出票:10
Thread-1--賣出票:10
Thread-2--賣出票:9
Thread-0--賣出票:9
Thread-2--賣出票:8
Thread-1--賣出票:9
Thread-2--賣出票:7
Thread-0--賣出票:8
Thread-2--賣出票:6
Thread-2--賣出票:5
Thread-2--賣出票:4
Thread-1--賣出票:8
Thread-2--賣出票:3
Thread-0--賣出票:7
Thread-2--賣出票:2
Thread-2--賣出票:1
Thread-1--賣出票:7
Thread-0--賣出票:6
Thread-1--賣出票:6
Thread-0--賣出票:5
Thread-0--賣出票:4
Thread-1--賣出票:5
Thread-0--賣出票:3
Thread-1--賣出票:4
Thread-1--賣出票:3
Thread-1--賣出票:2
Thread-0--賣出票:2
Thread-1--賣出票:1
Thread-0--賣出票:1
每個執行緒都獨立,不共享資源,每個執行緒都賣出了10張票,總共賣出了30張。如果真賣票,就有問題了。
實現Runnable介面方式
package multithreading;
public class MyThreadWithImplements implements Runnable {
private int tickets = 10;
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
if(tickets>0){
System.out.println(Thread.currentThread().getName()+"--賣出票:" + tickets--);
}
}
}
public static void main(String[] args) {
MyThreadWithImplements myRunnable = new MyThreadWithImplements();
Thread thread1 = new Thread(myRunnable, "視窗一");
Thread thread2 = new Thread(myRunnable, "視窗二");
Thread thread3 = new Thread(myRunnable, "視窗三");
thread1.start();
thread2.start();
thread3.start();
}
}
執行結果:
視窗二--賣出票:10
視窗三--賣出票:9
視窗一--賣出票:8
視窗三--賣出票:6
視窗三--賣出票:4
視窗三--賣出票:3
視窗三--賣出票:2
視窗三--賣出票:1
視窗二--賣出票:7
視窗一--賣出票:5
每個執行緒共享了物件myRunnable的資源,賣出的總票數是對的,但是順序是亂的,怎麼辦?