於Java好的方面是它有內置的寫多線程的支持Java的設計者知道多線程編程的價值所以聰明決定在Java的核心部分就決定直接支持線程在第章並發存取對象和變量就闡述了在Java語言中synchronized關鍵字如何被用來鎖住對象和類來控制並發存取數據Thread和ThreadGroup類就在javalang包的核心API中通過wait( ) notify( ) 方法的支持Java中所有類的父類Object具有線程間通信的能力即使當前操作系統不支持線程概念一個寫好的JVM也可以模擬多線程環境在Java中線程的支持不是事後的而是從一開始設計時就包括進來的
一個簡單的兩個線程例子
概述
這章展示了創建並在一個小的Java應用中運行線程是如何簡單第一個線程是總是有JVM創建的main線程該線程開始運行程序這個主線程然後創建第二個線程每個線程將在控制台打印各自信息以此來證明他們好像以同步方式運行
這章中例子創建一個線程的步驟如下
繼承javalangThread類
在繼承Thread的子類中重寫run( )方法
創建這個新類的實例
調用該實例的start( )方法
繼承javalangthread類
在JavaVM中每個線程與javalangThread類的一個實例想關聯這些Thread對象作為與底層操作系統線程交互的接口通過類中的方法可以對線程進行開始停止中斷命名設置優先級和查詢有關當前狀態
注意有兩種方式可創建一個允許線程運行與其中的類一種方式是繼承Thread類另一種是繼承任意類並且實現Runnable接口為了說明的原因繼承Thread類是最簡單的方法本書開始就是用該方法在實際中實現Runnable接口工作地更好些
在這個例子中創建一個新線程的第一步是繼承javalangThread類
Java代碼
public class TwoThread extends Thread {
//
}
TwoThread子類是一個(ISA) Thread並且繼承了父類的protected 和public成員TwoThread除了從父類中繼承的其他行為之外它還能被開始停止中斷命名設置優先級以及查詢線程當前狀態
重寫run()方法
繼承Thread類之後下一步就是重寫run()方法因為Thread類中方法什麼也沒做
Public void run() { }
當一個新線程開始運行進入該線程的入口就是run()方法run()中的第一條語句就是新線程執行的第一條語句線程執行的每條語句都包含在run()方法中或包含在被run()方法直接或間接調用的其他方法中從run()被調用之前到run()返回新線程被認為是活著的run()返回之後線程就死掉了當一個線程死了之後不能重新開始
在本章的例子中run()方法被重寫為迭代次並且每次打印New thread信息
Java代碼
public void run() {
for ( int i = ; i < ; i++ ) {
Systemoutprintln(New thread);
}
}
循環完成之後線程從run()方法返回然後安靜死掉
創建一個新線程 Spawning a New Thread
新線程從已經運行的線程來創建首先構造一個新Thread實例在此例中一個新TwoThread對象將正好因為TwoThread ISA Thread
TwoThread tt = new TwoThread();
下一步是調用start()方法准備開始執行線程(start()從Thread繼承而來)
ttstart();
start()調用後立即返回不需要等待其他線程開始執行在start()中父線程異步地從JavaVM中給線程調度程序發出信號告訴它只要它方便其他線程可以開始執行了在未來某個不可預期的時間裡其他線程將被激活並調用Thread對象的run()方法(在該例中是指TwoThread中實現的重寫方法run())與此同時原來的線程繼續執行start()方法後面的語句
兩個線程並發獨立地運行在一個多處理器的機器上這兩個線程可能在同一時刻真正都在運行各自運行在自己的處理器上
一個更常見的情況是只有一個處理器JavaVM和操作系統共同工作來短時間調度每個線程當其他線程被凍結等待處理器的下一次機會時每個線程就得到一次運行的機會這種在線程之間的上下文切換是非常快的給人一種同時執行的假象
提示一個新創建的線程可能在start()被調用之後的任何時間開始執行(進入run()方法)這意味著start()方法之後的任何語句被執行之前原來線程都可能被換出(swapped out)
假如原來的線程正在執行下面的代碼
stmt();
ttstart();
新線程有一個run()方法如下
Java代碼
public void run() {
stmtA();
stmtB();
}
stmt();
處理器中實際執行的語句順序可能是stmt() ttstart() stmt() stmtA() and stmtB()也可能是stmt() ttstart() stmtA() stmtB() and stmt()也許還可能是另外一種順序
重要的是要記住盡管每個線程將執行各自語句的順序是已知和簡單的但是實際運行在處理器上的語句卻是不確定的對於程序的正確性而言沒有一種特殊的順序可以依賴
把所有放在一起
TwoThreadjava shown in Listing
Listing TwoThreadjava—The Complete Code for the TwoThread Example
Java代碼
: public class TwoThread extends Thread {
: public void run() {
: for ( int i = ; i < ; i++ ) {
: Systemoutprintln(New thread);
: }
: }
:
: public static void main(String[] args) {
: TwoThread tt = new TwoThread();
: ttstart();
:
: for ( int i = ; i < ; i++ ) {
: Systemoutprintln(Main thread);
: }
: }
: }
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26116.html