【Java多線程編程核心技術】第一章(多線程技能)

Thread類的核心方法較多,讀者應該着重掌握如下關鍵技術點:

□線程的啓動

□如果使線程暫停

□如何使線程停止

□線程的優先級

□線程安全相關的問題

1.1 進程與多線程的概念及線程的優點

     本節主要介紹在Java語言中使用多線程技術。但是講到多線程不得不提到進程這個概念:

進程(Process)是計算機中的程序關於某數據集合上的一次運行活動,
是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。在早
期面向進程設計的計算機結構中,進程是程序的基本執行實體;在當代
面向線程設計的計算機結構中,進程是線程的容器。程序是指令、數據
及其組織形式的描述,進程是程序的實體。

    將一個正在操作系統中運行的exe程序理解成一個進程!通過查看任務管理器中的列表,完全可以將運行在內存中的exe文件理解成進程,進程是受操作系統管理的基本運行單元。

   那什麼是線程呢?線程可以理解成是進程中獨立運行的子任務。比如,QQ.exe運行時就有很多的子任務在同時運行。再如,好友視頻線程,下載文件線程,傳輸數據線程等等,這些不同的任務或者說功能都可以同時運行,其中每一項任務完全可以理解成是線程在工作。使用多任務操作系統後,可以最大限度地利用CPU的空閒時間來處理其它的任務,比如一邊打印,一邊使用word編輯。而CPU在這些任務之間不停地切換,由於切換速度非常快,給使用者的感覺就是這些任務似乎在同時運行。所以在使用多線程技術後,可以在同一時間內運行更多不同種類的任務。

1.2 使用多線程

  一個進程正在運行時至少會有一個線程在運行,這種情況在java中也是存在的。這些線程在後臺默默地執行:

	public static void main(String[] args) {
		System.out.println(Thread.currentThread().getName());// main
	}

  在控制檯輸出的main其實就是一個名稱叫做main的線程在執行main方法中的代碼。另外需要說明一下,在控制檯輸出的main和main方法沒有任何的關係,僅僅是名字相同而已

1.2.1 繼承Thread類

         實現多線程編程的方式有兩種,一種是繼承Thread類,另一種是實現Runnable接口。先來看看Thread類的結構:

public class Thread implements Runnable

        從源代碼可以發現,Thread類實現了Runnable接口,它們之間具有多態關係。其實,使用繼承Thread類的方式創建線程時,最大的侷限就是不支持多繼承,因爲Java語言的特點就是單根繼承,所以爲了支持多繼承,完全可以實現Runnable接口的方式,一邊實現一邊繼承。

public class MyThread extends Thread {
	@Override
	public void run() {
		super.run();
		System.out.println("My Thread!");
	}	
	public static void main(String[] args) {
		MyThread my = new MyThread();
		my.start();
		System.out.println("運行結束");// 運行結束/n My Thread!
	}
}

        以上代碼的打印順序可以看出來,run方法執行的時間比較晚,這也說明在使用多線程技術時,代碼的運行結果與代碼執行順序或調用順序無關

       上面代碼介紹了線程的調用的隨機性,下面將演示線程的隨機性。

public class MyThread extends Thread {

	@Override
	public void run() {
		try {
			for(int i=0; i<10; i++) {
				int time = (int)(Math.random()*1000);
				Thread.sleep(time);
				System.out.println("run="+Thread.currentThread().getName());
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		MyThread my = new MyThread();
		my.setName("myThread");
		my.start();
		
		try {
			for(int i=0; i<10; i++) {
				int time = (int)(Math.random()*1000);
				Thread.sleep(time);
				System.out.println("main="+Thread.currentThread().getName());
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

       在代碼中,爲了展現出線程具有隨機特性,所以使用隨機數的形式來使線程得到掛起的效果,從而表現出CPU執行哪個線程具有不確定性。Thread.java類中的start方法通過‘線程規劃器‘此線程已經準備就緒,等待調用線程對象的run方法。這個過程其實就是讓系統安排一個時間來調用Thread中的run方法,也就是線程得到運行,啓動線程,具有異步執行的效果。如果直接調用代碼thread.run就不是異步執行。 而是同步,那麼此線程對象並不會交給"線程規劃器"來進行處理,而是由main主線程來調用run方法,也就是必須等run方法中的代碼執行完成後才能執行後面的代碼。(看下面代碼中的註釋)

    public static void main(String[] args) {
		MyThread my = new MyThread();
		my.setName("myThread");
		my.run();// 由start替換成run,運行結果發生變化,先執行完線程裏面的,然後再執行main方法裏面的	
		try {
			for(int i=0; i<10; i++) {
				int time = (int)(Math.random()*1000);
				Thread.sleep(time);
				System.out.println("main="+Thread.currentThread().getName());
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

 

 

 

 

 

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