1. java中thread的start()和run()有何區別
1、start()方法來啟動線程,真正實現了多線程運行,這時無需等待。
run方法體代碼執行完畢而直接繼續執行下面的代碼;通過調用Thread類的start()方法來啟動一個線程,這時此線程是處於就緒狀態,並沒有運行。
通過Thread類調用方法run()來完成其運行操作的,這里方法run()稱為線程體,它包含了要執行的這個線程的內容,Run方法運行結束,此線程終止,而CPU再運行其它線程。
2、run()方法當作普通方法的方式調用,程序還是要順序執行,還是要等待run方法體執行完畢後才可繼續執行下面的代碼;
而如果直接用run方法,這只是調用一個方法而已,程序中依然只有主線程--這一個線程,其程序執行路徑還是只有一條,這樣就沒有達到寫線程的目的。
3、調用start方法方可啟動線程,而run方法只是thread的一個普通方法調用,還是在主線程里執行。
4、這兩個方法需要把並行處理的代碼放在run()方法中,start()方法啟動線程將自動調用 run()方法,這是由jvm的內存機制規定的。並且run()方法必須是public訪問許可權,返回值類型為void.。
(1)java多線程編程總結擴展閱讀:
用start方法來啟動線程,真正實現了多線程運行,這時無需等待run方法體代碼執行完畢而直接繼續執行下面的代碼。
通過調用Thread類的start()方法來啟動一個線程,這時此線程處於就緒(可運行)狀態,並沒有運行,一旦得到cpu時間片,就開始執行run()方法,這里方法 run()稱為線程體,它包含了要執行的這個線程的內容,Run方法運行結束,此線程隨即終止。
run()方法只是類的一個普通方法而已,如果直接調用Run方法,程序中依然只有主線程這一個線程,其程序執行路徑還是只有一條,還是要順序執行,還是要等待run方法體執行完畢後才可繼續執行下面的代碼,這樣就沒有達到寫線程的目的。
2. 如何學習java多線程這塊
學習Java其實應該上升到如何學習程序設計這種境界,其實學習程序設計又是接受一種編程思想。每一種語言的程序設計思想 大同小異,只是一些由語言特性的而帶來的細微差別,比如Java中的Interface,你幾乎在以前的學習中沒有碰到過。以下9點是「小舒的博客」總結的學習筆記,希望對你有所幫助!!
1。我們必須明確一個大方向,也就是說現在面向對象的編程范疇。盡管人工智慧曾經有所浪潮(看看Borland為什麼有TurboProlog),但未來5-10年工業界廣泛承認並接受的將是面向對象式的編程。
2。工業界目前最流行的面向對象編程語言就是C++和Java。所以基本上鎖定這兩個方向就可以了。而且完全可以同時掌握。
3。掌握Java的精華特性而且一定要知道為什麼。比如,Interface和multi-thread。用interface是更好的多繼承的模型,而多線程則是設計到語言一級的重要特性。要完全理解interface是為什麼,用多線程又有幾種常用的編程模型。
4。理解了語言的特性是為什麼了之後,就可以試著上升到設計這個層次,畢竟學習語言是要用的。目前比較好的開發模式是採用自定向下的面向對象的設計,加上MVC的模式(你可以看一下我介紹的關於MVC的內容)。首先要找出最頂層的對象(這往往是最難的),然後一層一層往下遞歸,記住每次應符合7+/-2的原則,因為我們人的短記憶就是這樣。一般有圖形用戶界面的應從界面開始設計。
5。有了基本設計模型後,可以學一些設計模式(Design Pattern)。這是目前證明很有效的。比如體系結構模式(Layering分層,
Pipe/Filter管道或過濾器),設計模式(有很多,比如對象池Object Pool、緩沖池Cache等),編程模式(比如Copy-on-Write)。
懂了這些模式之後,就會對系統的整體結構有很好的把握,而學術上也有傾向一個系統完全可以由各種模式組合而成。前面提到的MT實際上就有好幾種模式,掌握後就不用自己花很多時間去試了。另外一個很重要的領域就是並行和分布式計算領域,大概有20種左右。
6。接下來就不能紙上談兵了,最好的方法其實是實踐。一般教科書上的例子並不能算是實踐,只能算是讓你掌握語言特性用的。而提倡做實際的Project也不是太好,因為你還沒有熟練的能力去綜合各種技術,這樣只能是你自己越來越迷糊。我認為比較好的方法是找一些比較經典的例子,每個例子比較集中一種編程思想而設計的。從HotDraw上我學到了什麼是Framework,以及如何用rolemodel的方式來構造,這樣我就可以應用到其他的地方。順便說一句,這個例子你絕對不會覺得小,只會覺得大,並且他還是真正的商用的Framework。
7。結合前面學到的設計模式你就可以很好的理解這些經典的例子。並且自己可以用他來實現一些簡單的系統。如果可以對他進行進一步的修改,找出你覺得可以提高性能的地方,加上自己的設計,那就更上一個層次了,也就會真正地感到有所收獲。
8。好象以上談的跟Java沒什麼關系,其實我們早就應該從單純的學習語言到真正的學習好編程的領域。學習技術是沒有止境的,你學習第一種語言可能要半年時間,以後每種語言都不應該超過兩個月,否則你會覺得學習語言是包袱,是痛苦。
9。學習是為了用的,是為了讓你的程序產生價值,把握住這個原則會比較輕松點。
加油吧!!!
3. java多線程開發的同步機制有哪些
Java同步
標簽: 分類:
一、關鍵字:
thread(線程)、thread-safe(線程安全)、intercurrent(並發的)
synchronized(同步的)、asynchronized(非同步的)、
volatile(易變的)、atomic(原子的)、share(共享)
二、總結背景:
一次讀寫共享文件編寫,嚯,好傢伙,竟然揪出這些零碎而又是一路的知識點。於是乎,Google和翻閱了《Java參考大全》、《Effective Java Second Edition》,特此總結一下供日後工作學習參考。
三、概念:
1、 什麼時候必須同步?什麼叫同步?如何同步?
要跨線程維護正確的可見性,只要在幾個線程之間共享非 final 變數,就必須使用 synchronized(或 volatile)以確保一個線程可以看見另一個線程做的更改。
為了在線程之間進行可靠的通信,也為了互斥訪問,同步是必須的。這歸因於java語言規范的內存模型,它規定了:一個線程所做的變化何時以及如何變成對其它線程可見。
因為多線程將非同步行為引進程序,所以在需要同步時,必須有一種方法強制進行。例如:如果2個線程想要通信並且要共享一個復雜的數據結構,如鏈表,此時需要
確保它們互不沖突,也就是必須阻止B線程在A線程讀數據的過程中向鏈表裡面寫數據(A獲得了鎖,B必須等A釋放了該鎖)。
為了達到這個目的,java在一個舊的的進程同步模型——監控器(Monitor)的基礎上實現了一個巧妙的方案:監控器是一個控制機制,可以認為是一個
很小的、只能容納一個線程的盒子,一旦一個線程進入監控器,其它的線程必須等待,直到那個線程退出監控為止。通過這種方式,一個監控器可以保證共享資源在
同一時刻只可被一個線程使用。這種方式稱之為同步。(一旦一個線程進入一個實例的任何同步方法,別的線程將不能進入該同一實例的其它同步方法,但是該實例
的非同步方法仍然能夠被調用)。
錯誤的理解:同步嘛,就是幾個線程可以同時進行訪問。
同步和多線程關系:沒多線程環境就不需要同步;有多線程環境也不一定需要同步。
鎖提供了兩種主要特性:互斥(mutual exclusion) 和可見性(visibility)。
互斥即一次只允許一個線程持有某個特定的鎖,因此可使用該特性實現對共享數據的協調訪問協議,這樣,一次就只有一個線程能夠使用該共享數據。
可見性要更加復雜一些,documents它必須確保釋放鎖之前對共享數據做出的更改對於隨後獲得該鎖的另一個線程是可見的 —— 如果沒有同步機制提供的這種可見性保證,線程看到的共享變數可能是修改前的值或不一致的值,這將引發許多嚴重問題
小結:為了防止多個線程並發對同一數據的修改,所以需要同步,否則會造成數據不一致(就是所謂的:線程安全。如java集合框架中Hashtable和
Vector是線程安全的。我們的大部分程序都不是線程安全的,因為沒有進行同步,而且我們沒有必要,因為大部分情況根本沒有多線程環境)。
2、 什麼叫原子的(原子操作)?
Java原子操作是指:不會被打斷地的操作。(就是做到互斥 和可見性?!)
那難道原子操作就可以真的達到線程安全同步效果了嗎?實際上有一些原子操作不一定是線程安全的。
那麼,原子操作在什麼情況下不是線程安全的呢?也許是這個原因導致的:java線程允許線程在自己的內存區保存變數的副本。允許線程使用本地的私有拷貝進
行工作而非每次都使用主存的值是為了提高性能(本人愚見:雖然原子操作是線程安全的,可各線程在得到變數(讀操作)後,就是各自玩
弄自己的副本了,更新操作(寫操作)因未寫入主存中,導致其它線程不可見)。
那該如何解決呢?因此需要通過java同步機制。
在java中,32位或者更少位數的賦值是原子的。在一個32位的硬體平台上,除了double和long型的其它原始類型通常都
是使用32位進行表示,而double和long通常使用64位表示。另外,對象引用使用本機指針實現,通常也是32位的。對這些32位的類型的操作是原
子的。
這些原始類型通常使用32位或者64位表示,這又引入了另一個小小的神話:原始類型的大小是由語言保證的。這是不對的。java語言保證的是原始類型的表
數范圍而非JVM中的存儲大小。因此,int型總是有相同的表數范圍。在一個JVM上可能使用32位實現,而在另一個JVM上可能是64位的。在此再次強
調:在所有平台上被保證的是表數范圍,32位以及更小的值的操作是原子的。
3、 不要搞混了:同步、非同步
舉個例子:普通B/S模式(同步)AJAX技術(非同步)
同步:提交請求->等待伺服器處理->處理完返回 這個期間客戶端瀏覽器不能幹任何事
非同步:請求通過事件觸發->伺服器處理(這是瀏覽器仍然可以作其他事情)->處理完畢
可見,彼「同步」非此「同步」——我們說的java中的那個共享數據同步(synchronized)
一個同步的對象是指行為(動作),一個是同步的對象是指物質(共享數據)。
4、 Java同步機制有4種實現方式:(部分引用網上資源)
① ThreadLocal ② synchronized( ) ③ wait() 與 notify() ④ volatile
目的:都是為了解決多線程中的對同一變數的訪問沖突
ThreadLocal
ThreadLocal 保證不同線程擁有不同實例,相同線程一定擁有相同的實例,即為每一個使用該變數的線程提供一個該變數值的副本,每一個線程都可以獨立改變自己的副本,而不是與其它線程的副本沖突。
優勢:提供了線程安全的共享對象
與其它同步機制的區別:同步機制是為了同步多個線程對相同資源的並發訪問,是為了多個線程之間進行通信;而 ThreadLocal 是隔離多個線程的數據共享,從根本上就不在多個線程之間共享資源,這樣當然不需要多個線程進行同步了。
volatile
volatile 修飾的成員變數在每次被線程訪問時,都強迫從共享內存中重讀該成員變數的值。而且,當成員變數發生變化時,強迫線程將變化值回寫到共享內存。
優勢:這樣在任何時刻,兩個不同的線程總是看到某個成員變數的同一個值。
緣由:Java
語言規范中指出,為了獲得最佳速度,允許線程保存共享成員變數的私有拷貝,而且只當線程進入或者離開同步代碼塊時才與共享成員變數的原
始值對比。這樣當多個線程同時與某個對象交互時,就必須要注意到要讓線程及時的得到共享成員變數的變化。而 volatile
關鍵字就是提示 VM :對於這個成員變數不能保存它的私有拷貝,而應直接與共享成員變數交互。
使用技巧:在兩個或者更多的線程訪問的成員變數上使用 volatile 。當要訪問的變數已在 synchronized 代碼塊中,或者為常量時,不必使用。
線程為了提高效率,將某成員變數(如A)拷貝了一份(如B),線程中對A的訪問其實訪問的是B。只在某些動作時才進行A和B的同步,因此存在A和B不一致
的情況。volatile就是用來避免這種情況的。
volatile告訴jvm,它所修飾的變數不保留拷貝,直接訪問主內存中的(讀操作多時使用較好;線程間需要通信,本條做不到)
Volatile 變數具有 synchronized 的可見性特性,但是不具備原子特性。這就是說線程能夠自動發現 volatile
變數的最新值。Volatile
變數可用於提供線程安全,但是只能應用於非常有限的一組用例:多個變數之間或者某個變數的當前值與修改後值
之間沒有約束。
您只能在有限的一些情形下使用 volatile 變數替代鎖。要使 volatile 變數提供理想的線程安全,必須同時滿足下面兩個條件:
對變數的寫操作不依賴於當前值;該變數沒有包含在具有其他變數的不變式中。
sleep() vs wait()
sleep是線程類(Thread)的方法,導致此線程暫停執行指定時間,把執行機會給其他線程,但是監控狀態依然保持,到時後會自動恢復。調用sleep不會釋放對象鎖。
wait是Object類的方法,對此對象調用wait方法導致本線程放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象發出notify方法(或notifyAll)後本線程才進入對象鎖定池准備獲得對象鎖進入運行狀態。
(如果變數被聲明為volatile,在每次訪問時都會和主存一致;如果變數在同步方法或者同步塊中被訪問,當在方法或者塊的入口處獲得鎖以及方法或者塊退出時釋放鎖時變數被同步。)
4. java,web程序設計要學些什麼
第一階段:Java基礎,包括java語法,面向對象特徵,常見API,集合框架; (基礎)
第二階段:java界面編程,包括AWT,事件機制,SWING,(不常用)這個部分也可以跳過,用的時候再看都能來及;
第三階段:java API:輸入輸出,多線程,網路編程,反射註解等,java的精華部分(重點);
第四階段:資料庫SQL基礎,包括增刪改查操作以及多表查詢; Oracle Mysql
第五階段:JDBC編程:包括JDBC原理,JDBC連接庫,JDBC API,雖然現在Hibernate比JDBC要方便許多,但是JDBC技術仍然在使用,JDBC思想尤為重要;
第六階段:JDBC深入理解高級特性:包括資料庫連接池,存儲過程,觸發器,CRM思想(高級)這個比較不好懂,有時間的可以學習;
第七階段:HTML語言學習,包括HTML標簽,表單標簽以及CSS,這是Web應用開發的基礎;
第八階段:JavaScript腳本語言,包括javaScript語法和對象,Ajax基礎 ;就這兩個方面的內容;
第九階段:Servlet開發,從此開始踏入javaWeb開發的重要一步,包括XML,Tomcat伺服器的安裝使用操作,HTTP協議簡單理解,Servlet API等,java web開發的基礎。 (重要)
第十階段:JSP開發:JSP語法和標簽,自定義標簽,EL,JSTL庫了解以及MVC三層架構的設計模式理念;
第十一階段:AJAX開發:AJAX原理,請求響應處理,AJAX開發庫,Jquery;
第十二階段:三大框架-struts、spring、hibernate,javaWeb的精華部分(重要)
第十三階段:其他框架學習-springMVC、mybatis,目前比較主流的框架
第十四階段:當學習完這些知識後,你就可以深層次的學習一些企業框架,Maven、redis、log4j等等
第十五階段:一般現在的公司企業用的系統伺服器都是linux,所以有興趣的可以學習一下,linux的各種命令
5. Java澶氱嚎紼嬮棶棰樻葷粨錛
Java澶氱嚎紼嬪垎綾諱腑鍐欎簡21綃囧氱嚎紼嬬殑鏂囩珷錛21綃囨枃絝犵殑鍐呭瑰緢澶氾紝涓浜鴻や負錛屽︿範錛屽唴瀹硅秺澶氥佽秺鏉傜殑鐭ヨ瘑錛岃秺闇瑕佽繘琛屾繁鍒葷殑鎬葷粨錛岃繖鏍鋒墠鑳借板繂娣卞埢錛屽皢鐭ヨ瘑鍙樻垚鑷宸辯殑銆俲ava璇劇▼鍩硅鏈烘瀯璁や負榪欑瘒鏂囩珷涓昏佹槸瀵瑰氱嚎紼嬬殑闂棰樿繘琛屾葷粨鐨勶紝鍥犳ょ綏鍒椾簡澶氫釜澶氱嚎紼嬬殑闂棰樸
榪欎簺澶氱嚎紼嬬殑闂棰橈紝鏈変簺鏉ユ簮浜庡悇澶х綉絝欍佹湁浜涙潵婧愪簬鑷宸辯殑鎬濊冦
錛1錛夊彂鎸ュ氭牳CPU鐨勪紭鍔
闅忕潃宸ヤ笟鐨勮繘姝ワ紝鐜板湪鐨勭瑪璁版湰銆佸彴寮忔満涔冭嚦鍟嗙敤鐨勫簲鐢ㄦ湇鍔″櫒鑷沖皯涔熼兘鏄鍙屾牳鐨勶紝4鏍搞8鏍哥敋鑷16鏍哥殑涔熼兘涓嶅皯瑙侊紝濡傛灉鏄鍗曠嚎紼嬬殑紼嬪簭錛岄偅涔堝湪鍙屾牳CPU涓婂氨嫻璐逛簡50%錛屽湪4鏍窩PU涓婂氨嫻璐逛簡75%銆傚崟鏍窩PU涓婃墍璋撶殑鈥濆氱嚎紼嬧濋偅鏄鍋囩殑澶氱嚎紼嬶紝鍚屼竴鏃墮棿澶勭悊鍣ㄥ彧浼氬勭悊涓孌甸昏緫錛屽彧涓嶈繃綰跨▼涔嬮棿鍒囨崲寰楁瘮杈冨揩錛岀湅鐫鍍忓氫釜綰跨▼鈥濆悓鏃垛濊繍琛岀艦浜嗐傚氭牳CPU涓婄殑澶氱嚎紼嬫墠鏄鐪熸g殑澶氱嚎紼嬶紝瀹冭兘璁╀綘鐨勫氭甸昏緫鍚屾椂宸ヤ綔錛屽氱嚎紼嬶紝鍙浠ョ湡姝e彂鎸ュ嚭澶氭牳CPU鐨勪紭鍔挎潵錛岃揪鍒板厖鍒嗗埄鐢–PU鐨勭洰鐨勩
錛2錛夐槻姝㈤樆濉
浠庣▼搴忚繍琛屾晥鐜囩殑瑙掑害鏉ョ湅錛屽崟鏍窩PU涓嶄絾涓嶄細鍙戞尌鍑哄氱嚎紼嬬殑浼樺娍錛屽弽鑰屼細鍥犱負鍦ㄥ崟鏍窩PU涓婅繍琛屽氱嚎紼嬪艱嚧綰跨▼涓婁笅鏂囩殑鍒囨崲錛岃岄檷浣庣▼搴忔暣浣撶殑鏁堢巼銆備絾鏄鍗曟牳CPU鎴戜滑榪樻槸瑕佸簲鐢ㄥ氱嚎紼嬶紝灝辨槸涓轟簡闃叉㈤樆濉炪傝瘯鎯籌紝濡傛灉鍗曟牳CPU浣跨敤鍗曠嚎紼嬶紝閭d箞鍙瑕佽繖涓綰跨▼闃誨炰簡錛屾瘮鏂硅磋繙紼嬭誨彇鏌愪釜鏁版嵁鍚э紝瀵圭榪熻繜鏈榪斿洖鍙堟病鏈夎劇疆瓚呮椂鏃墮棿錛岄偅涔堜綘鐨勬暣涓紼嬪簭鍦ㄦ暟鎹榪斿洖鍥炴潵涔嬪墠灝卞仠姝㈣繍琛屼簡銆傚氱嚎紼嬪彲浠ラ槻姝㈣繖涓闂棰橈紝澶氭潯綰跨▼鍚屾椂榪愯岋紝鍝鎬曚竴鏉$嚎紼嬬殑浠g爜鎵ц岃誨彇鏁版嵁闃誨烇紝涔熶笉浼氬獎鍝嶅叾瀹冧換鍔$殑鎵ц屻
錛3錛変究浜庡緩妯
榪欐槸鍙﹀栦竴涓娌℃湁榪欎箞鏄庢樉鐨勪紭鐐逛簡銆傚亣璁炬湁涓涓澶х殑浠誨姟A錛屽崟綰跨▼緙栫▼錛岄偅涔堝氨瑕佽冭檻寰堝氾紝寤虹珛鏁翠釜紼嬪簭妯″瀷姣旇緝楹葷儲銆備絾鏄濡傛灉鎶婅繖涓澶х殑浠誨姟A鍒嗚В鎴愬嚑涓灝忎換鍔★紝浠誨姟B銆佷換鍔C銆佷換鍔D錛屽垎鍒寤虹珛紼嬪簭妯″瀷錛屽苟閫氳繃澶氱嚎紼嬪垎鍒榪愯岃繖鍑犱釜浠誨姟錛岄偅灝辯畝鍗曞緢澶氫簡銆