線程

一. 線程和進程

1.1 併發與並行

  • 併發:指兩個或多個事件在同一時間段內發生的。(交替執行)
  • 並行:指兩個或多個事件在同一時刻發生。(同時執行)

1.2 線程與進程

  • 進程:指正在運行中的應用程序,每個進程都有一個獨立的內存空間,進程是程序的一次執行過程,是系統運行程序的基本單位。每當用戶啓動一個進程時,操作系統爲該進程分配一個獨立的內存空間,讓進程在這個獨立內存空間運行。
  • 線程:線程是進程中的一個執行單元,負責當前進程中程序的執行,一個進程中至少有一個線程。

主線程:

JVM執行main方法,main方法就會進入棧內存,JVM會找操作系統開闢一條main方法通向cpu的執行路徑,cup就可以通過這個路徑來執行main方法,而這個路徑有一個名字,叫(主)線程。

線程調度:

  • 分時調度

    所有線程輪流使用 CPU 的使用權,平均分配每個線程佔用 CPU 的時間。

  • 搶佔式調度

    優先讓優先級高的線程使用 CPU,如果線程的優先級相同,那麼會隨機選擇一個(線程隨機性),Java使用的爲搶佔式調度。

1.3 創建線程類

Java使用 java.lang.Thread 類代表線程,所有的線程對象都必須是Thread類或其子類的實例。

Java中通過繼承Thread類來創建並啓動多線程的步驟如下:

  1. 定義Thread類的子類,並重寫該類的run()方法,該run()方法的方法體就代表了線程需要完成的任務,因此把run()方法稱爲線程執行體。

  2. 創建Thread子類的實例,即創建了線程對象。

  3. 調用線程對象的start()方法來啓動該線程。

    public class Demo01 {
	 public static void main(String[] args) {
		//創建自定義線程對象,設置線程名稱
		MyThread mt = new MyThread("新的線程!");
		//開啓新線程
		mt.start();
		//在主方法中執行for循環
		for (int i = 0; i < 10; i++) {
			System.out.println("main線程!"+i);
		}
	  }
    }

 測試類:

   public class MyThread extends Thread {
	//定義指定線程名稱的構造方法
	public MyThread(String name) {
		//調用父類的String參數的構造方法,指定線程的名稱
		super(name);
	}
	/**
	 * 重寫run方法,線程執行邏輯
	 */
	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			System.out.println(getName()+":正在執行!"+i);
	        }
	 }
    }

二. 多線程

2.1 多線程原理

多線程執行時,在棧內存中,每一個執行線程都有一片自己所屬的棧內存空間。進行方法的壓棧和彈棧。

當執行線程的任務結束了,線程自動在棧內存中釋放了,當所有的執行線程都結束了,進程也就結束了。

2.2 Thread類
構造方法:

public Thread() :分配一個新的線程對象。
public Thread(String name) :分配一個指定名字的新的線程對象。
public Thread(Runnable target) :分配一個帶有指定目標新的線程對象。
public Thread(Runnable target,String name) :分配一個帶有指定目標新的線程對象並指定名字。

常用方法:

public String getName() :獲取當前線程名稱。
public void start() :線程開始執行; Java虛擬機調用此線程的run方法。
public void run() :此線程要執行的任務。
public static void sleep(long millis) :使當前正在執行的線程以指定的毫秒數暫停(暫時停止執行)。 
public static Thread currentThread() :返回對當前正在執行的線程對象的引用。

2.3 創建線程第二種方式

第一種方式是繼承Thread類,第二種是實現Runnable接口,重寫run方法。

實現步驟:

1. 定義Runnable接口的實現類,重寫該接口的run方法,定義線程任務。

2. 創建Runnable實現類的對象,並將此對象作爲Thread的target來創建Thread對象。該Thread對象纔是真正的線程對象。

3. 線程對象調用start方法啓動線程,執行run方法。

實現Runnable接口創建多線程程序的好處:

1. 避免了單繼承的侷限性

一個類只能繼承一個類,類繼承了Thread類就不能繼承其他類

實現Runnbale接口,還可以繼承其他的類。

2. 增強了程序的擴展性,降低了程序的耦合

實現Runnable接口的方式,把設置線程任務和開啓線程進行分離。(分藕)

實現類中,重寫了run方法:用來設置線程任務,創建Thread類,調用start方法開啓線程。

//Runnable接口實現類
public class RunnableImpl implements Runnable{
    //在實現類中重寫Runnbale接口的run方法,設置線程任務
    @Override
    public void run() {
        for (int i = 0; i <20 ; i++) {
            System.out.println(Thread.currentThread().getName()+"->"+i);
        }
    }
}
public class Demo01Runnable {
    public static void main(String[] args) {
        //創建一個Runnable接口的實現類對象
        RunnableImpl run = new RunnableImpl();
        //創建Thread類對象,構造方法中傳遞Runnable接口的實現類對象
        Thread t = new Thread(run);
        //調用Thread類中的start方法,開啓新的線程執行run方法
        t.start();
        for (int i = 0; i <20 ; i++) {
            System.out.println(Thread.currentThread().getName()+"-->"+i);
        }
    }
}

2.4 匿名內部類實現線程創建

        //線程的父類是Thread
        //new Thread().start();
        new Thread(){
            //重寫run方法,設置線程任務
            @Override
            public void run() {
                for (int i = 0; i <20 ; i++) {
                    System.out.println(Thread.currentThread().getName()+"-->1");
                }
            }
        }.start();

        //線程的接口Runnable
        //Runnable r = new RunnableImpl() 多態
        Runnable r = new Runnable(){
            //重寫run方法
            @Override
            public void run() {
                for (int i = 0; i <20 ; i++) {
                    System.out.println(Thread.currentThread().getName()+"-->2");
                }
            }
        };
        new Thread(r).start();

 

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