進程與線程,java多線程的應用

一個程序至少有一個進程,一個進程至少有一個線程.

進程是程序在一個數據集合上的運行過程。它是系統進行資源分配和調度的一個獨立單位。

線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位。

關於進程的使用,可以限制進程的數量,我覺得這是一個例子,比如有的程序它不允許你多客戶端運行,如夢幻西遊,它能限制你的客戶端數量,可能就是從進程方面來做的,再比如LOL ,它只允許你運行一個客戶端。

區別:
進程和線程的主要差別在於它們是不同的操作系統資源管理方式。進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響,而線程只是一個進程中的不同執行路徑。線程有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等於整個進程死掉,所以多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差一些。但對於一些要求同時進行並且又要共享某些變量的併發操作,只能用線程,不能用進程。

1) 簡而言之,一個程序至少有一個進程,一個進程至少有一個線程.

2) 線程的劃分尺度小於進程,使得多線程程序的併發性高。

3) 另外,進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率。

4) 線程在執行過程中與進程還是有區別的。每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。

5) 從邏輯角度來看,多線程的意義在於一個應用程序中,有多個執行部分可以同時執行。但操作系統並沒有將多個線程看做多個獨立的應用,來實現進程的調度和管理以及資源分配。這就是進程和線程的重要區別。

爲什麼要用多線程?

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

我們平時習慣的主函數就是一個線程,這個時候,如果我們在主函數中有一個非常耗時的操作,比如連接網絡,連接數據庫,或者大量的計算等等,在主函數的主線程中執行這些操作,帶來的後果將是,在這些耗時操作完成之前,其他操作無法進行。比如在這個耗時操作之後有繪製UI的操作,這個時候,很可能會等上十幾秒UI才能顯示出來,這樣的結果肯定會非常不好。
那麼爲了解決上述問題,我們就要使用多線程,在主線程外設置一個子線程,這樣把耗時操作放在子線程中,主線程中運行一些簡單的操作,如UI繪製等,這樣就不會出現顯示UI卡死的狀況。

java中使用多線程 有兩種方法: 繼承Thread類, 實現Runable接口。
1

/**
 * 因爲輸出10個數比較小,當你啓動啓動第二個線程時第一個線程已經運行完畢,
 * 所以兩次輸出都是順序輸出,要麼將i設置很大很大,要麼讓每次打印暫停一下
 * @author Administrator
 *
 */
public class ThreadTest {
    public static void main(String[] args) {
        MyThread mt1 = new MyThread("線程A");
        MyThread mt2 = new MyThread("線程B");
        mt1.start();
        mt2.start();
    }
}


class MyThread extends Thread {
    private String name;

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

    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(name + "運行,i=" + i);
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }   
            }
    }
}

2

/**
 * 兩個線程不一定誰先執行
 * @author Administrator
 *
 */

public class RunableTest {

    public static void main(String[] args) {
        System.out.println("主線程ID:" + Thread.currentThread().getId());
        MyRunableThread runableThread1 = new MyRunableThread("線程1");
        MyRunableThread runableThread2 = new MyRunableThread("線程2");
        Thread thread1 = new Thread(runableThread1);
        Thread thread2 = new Thread(runableThread2);
        thread2.start();
        thread1.run();
    }

}

class MyRunableThread implements Runnable {
    String name;

    public MyRunableThread(String string) {
        this.name = string;
    }

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

    }

}

這裏寫圖片描述
通過start()方法去啓動線程。注意,不是調用run()方法啓動線程,run方法中只是定義需要執行的任務,如果調用run方法,即相當於在主線程中執行run方法,跟普通的方法調用沒有任何區別,此時並不會創建一個新的線程來執行定義的任務。

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

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章