java的線程中的Runnable

                  在java中可有兩種方式實現多線程,一種是繼承Thread類,一種是實現Runnable接口;Thread類是在java.lang包中定義的。一個類只要繼承了Thread類同時覆寫了本類中的run()方法就能夠實現多線程操做了,可是一個類只能繼承一個父類,這是此方法的侷限。java

可是實際在使用過程你會發現一些令你迷惑的問題,就來看下吧下面的代碼:多線程

public class SeThread implements Runnable {

	private int i;

	@Override
	public void run() {
		for (; i < 20; i++) {

				System.out.println(Thread.currentThread().getName() + "  i= "+ i);


		}

	}

	public static void main(String[] args) {
		for (int i = 0; i < 100; i++) {
			if (i == 20) {
				SeThread st = new SeThread();
				new Thread(st, "線程1").start();
				new Thread(st, "線程2").start();
			}
		}
	}
	
	

}

 

能夠看到,st是一個Runnable接口實現類的對象,可是卻被兩個線程做爲參數,啊啊。這個打印結果是什麼玩意??ide

BaiduShurufa_2014-3-22_17-33-33

  看到這或許你已經猜到了,這個是兩個Thread的外殼下竟然是同一顆跳到的Runnable心,那麼仍是看下Thread的實現吧。this

public
class Thread implements Runnable {

 public synchronized void start() {
       
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

    private native void start0();

 @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

//……
}

其實,Thread就是Runnable實現類,在調用start過程當中,咱們能夠知道它實現調用的是一個start0()這個本地方法,這個從咱們之前開發用的方法可知,確定是在CPU資源分配過程當中的某個時機調用了Thread的run()方法了,而run()方法實現的執行體就是傳入的Runnable對象的runnable。.net

因此兩個Thread的執行體,就是同一個runnale對象了,這個看上去是兩個線程,可實際上只有一個執行體那就是st對象啦,打印結果確定是如上圖看到的那樣了。線程

其實這個打印有兩個0,可知線程未同步,咱們能夠在處理打印這個方法作個同步修飾synchronized,這樣就能夠正確的打印從0到99啦。code

相關文章
相關標籤/搜索