1. 程式人生 > >Java並發編程:如何創建線程

Java並發編程:如何創建線程

運行 收集器 args 代碼 垃圾收集器 實例 windows win 線程編程

一.Java中關於應用程序和進程相關的概念

  在Java中,一個應用程序對應著一個JVM實例(也有地方稱為JVM進程),一般來說名字默認為java.exe或者javaw.exe(windows下可以通過任務管理器查看)。Java采用的是單線程編程模型,即在我們自己的程序中如果沒有主動創建線程的話,只會創建一個線程,通常稱為主線程。但是要註意,雖然只有一個線程來執行任務,不代表JVM中只有一個線程,JVM實例在創建的時候,同時會創建很多其他的線程(比如垃圾收集器線程)。

  由於Java采用的是單線程編程模型,因此在進行UI編程時要註意將耗時的操作放在子線程中進行,以避免阻塞主線程(在UI編程時,主線程即UI線程,用來處理用戶的交互事件)。

二.Java中如何創建線程

  在java中如果要創建線程的話,一般有兩種方式:1)繼承Thread類;2)實現Runnable接口。

  1.繼承Thread類

  繼承Thread類的話,必須重寫run方法,在run方法中定義需要執行的任務

class MyThread extends Thread {
    private static int num = 0;

    public MyThread() {
        num++;
    }

    @Override
    public void run() {
        System.out.println(
"主動創建的第" + num + "個線程"); } }

  創建好了自己的線程類之後,就可以創建線程對象了,然後通過start()方法去啟動線程。註意,不是調用run()方法啟動線程,run方法中只是定義需要執行的任務,如果調用run方法,即相當於在主線程中執行run方法,跟普通的方法調用沒有任何區別,此時並不會創建一個新的線程來執行定義的任務。

public class Test {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start();
    }
}


class MyThread extends Thread { private static int num = 0; public MyThread() { num ++; } @Override public void run() { System.out.println("主動創建的第" + num + "個線程"); } }

  在上面代碼中,通過調用start()方法,就會創建一個新的線程了。為了分清start()方法調用和run()方法調用的區別,請看下面一個例子:

public class Test {
    public static void main(String[] args) {

        System.out.println("主線程ID:" + Thread.currentThread().getId());
        MyThread thread1 = new MyThread("thread1");
        thread1.start();
        MyThread thread2 = new MyThread("thread2");
        thread2.run();
    }
}


class MyThread extends Thread {
    private String name;

    public MyThread(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println("name:" + name + " 子線程ID:" + Thread.currentThread().getId());
    }
}

運行結果:

主線程ID:1
name:thread2 子線程ID:1
name:thread1 子線程ID:11

  從輸出結果可以得出以下結論:

  1)thread1和thread2的線程ID不同,thread2和主線程ID相同,說明通過run方法調用並不會創建新的線程,而是在主線程中直接運行run方法,跟普通的方法調用沒有任何區別;

  2)雖然thread1的start方法調用在thread2的run方法前面調用,但是先輸出的是thread2的run方法調用的相關信息,說明新線程創建的過程不會阻塞主線程的後續執行。

  2.實現Runnable接口

  在Java中創建線程除了繼承Thread類之外,還可以通過實現Runnable接口來實現類似的功能。實現Runnable接口必須重寫其run方法。

  下面是一個例子:

public class Test {
    public static void main(String[] args) {
        System.out.println("主線程ID:" + Thread.currentThread().getId());
        MyRunnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        thread.start();
    }
}


class MyRunnable implements Runnable {

    public MyRunnable() {
    }

    @Override
    public void run() {
        System.out.println("子線程ID:" + Thread.currentThread().getId());
    }
}

  Runnable的中文意思是"任務",顧名思義,通過實現Runnable接口,我們定義了一個子任務,然後將子任務交由Thread去執行。註意,這種方式必須將Runnable作為Thread類的參數,然後通過Thread的start()方法來創建一個新線程來執行該子任務。如果調用Runnable的run方法的話,是不會創建新線程的,這跟普通的方法調用沒有任何區別。

  事實上,查看Thread類的實現源代碼會發現Thread類是實現了Runnable接口的。

  在Java中,這2種方式都可以用來創建線程去執行子任務,具體選擇哪一種方式要看自己的需求。直接繼承Thread類的話,可能比實現Runnable接口看起來更加簡潔,但是由於Java只允許單繼承,所以如果自定義類需要繼承其他類,則只能選擇實現Runnable接口。

參考:

http://www.cnblogs.com/dolphin0520/p/3913517.html

Java並發編程:如何創建線程