1. 程式人生 > >Java中Runnable和Thread的區別

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的資源,賣出的總票數是對的,但是順序是亂的,怎麼辦?