這個程序的不同運行將產生不同的結果這種不確定性來源於兩個方面在循環中有一個隨機的暫停更為重要的是因為線程執行時間沒法保證這是一個關鍵的原則JVM將根據它自己的時間表運行這些進程(虛擬機一般支持盡可能快地運行這些線程但是沒法保證何時運行一個給定線程)對於每個線程可以使一個優先級與之相關聯以確保關鍵線程被JVM處理在次要的線程之前
啟動一個線程的第二種方法是使用一個實現Runnable接口的類這個接口也定義在javalang中這個Runnable接口指定一個run()方法然後該方法成為線程的主函數類似於前面的代碼
現在Java程序的一般風格是支持繼承的接口通過使用接口一個類在後面仍然能夠繼承(子類化)如果必要的話(例如如果該類要在後面作為一個applet使用的話就會發生這種情況)
三線程的含義
在采用多線程技術增強性能的同時它也增加了程序內部運行的復雜性這種復雜性主要是由線程之間的交互引起的熟悉這些問題是很重要的因為隨著越來越多的核心芯片加入到Intel處理器中要使用的線程數目也將相應地增長如果在創建多線程程序時不能很好地理解這些問題那麼是調試時將很難發現錯誤因此讓我們先看一下這些問題及其解決辦法
等待另一個線程完成假定我們有一個整型數組要進行處理我們可以遍歷這個數組每次一個整數並執行相應的操作或更高效地我們可以建立多個線程這樣以來讓每個線程處理數組的一部分假定我們在開始下一步之前必須等待所有的線程結束為了暫時同步線程之間的活動這些線程使用了join()方法它使得一個線程等待另一個線程的完成加入的線程(線程B)等待被加入的線程(線程A)的完成在join()中的一個可選的超時值使得線程B可以繼續處理其它工作如果線程A在給定的時間幀內還沒有終止的話這個問題將觸及到線程的核心復雜性等待線程的問題下面我們將討論這個問題
在鎖定對象上等待假定我們編寫一個航空公司座位分配系統在開發這種大型的程序時為每個連接到該軟件的用戶分配一個線程是很經常的如一個線程對應一個機票銷售員(在很大的系統中情況並非總是如此)如果有兩個用戶同時想分配同一個座位就會出現問題除非采取特殊的措施否則一個線程將分配該座位而另一個線程將會在做相同的事情兩個用戶都會認為他們在這趟航班上擁有一個分配的位子
為了避免兩個線程同時修改一樣的數據項我們讓一個線程在修改數據前鎖定數據項用這種方法當第二個線程開始作修改時它將等待到第一個線程釋放鎖為止當這種發生時線程將會看到座位已被分配而對於座位分配的請求就會失敗兩個線程競爭分配座位的問題也就是著名的競爭條件問題而當競爭發生時有可能導致系統的洩漏為此最好的辦法就是鎖定任何代碼該代碼存取一個可由多個線程共同存取的變量
在Java中存在好幾種鎖選擇其中最為常用的是使用同步機制當一個方法的簽名包含同步時在任何給定時間只有一個線程能夠執行這個方法然後當該方法完成執行時對該方法的鎖定即被解除
就是一個方法在這種方法中每次只運行一個線程這種鎖機制就打破了上面所描述的競爭條件
使用同步是處理線程間交互的幾種方法中的一種JSE 中添加了若干方便的方法來鎖定對象大多數這些方法可以在包javautilconcurrentlocks中找到一旦你熟悉了Java線程就應該對它進行詳細的研究
在鎖機制解決了競爭條件的同時它們也帶來了新的復雜性在這種情況下最困難的問題就是死鎖假定線程A在等待線程B並且線程B在等待線程A那麼這兩個線程將永遠被鎖定這正是術語死鎖的意義死鎖問題可能很難判定並且必須相當小心以確保在線程之間沒有這種依賴性
[] [] [] []
From:http://tw.wingwit.com/Article/program/Java/gj/201311/27728.html