⑴ 如何用java編寫多線程
在java中要想實現多線程,有兩種手段,一種是繼續Thread類,另外一種是實現Runable介面。
對於直接繼承Thread的類來說,代碼大致框架是:
?
123456789101112 class 類名 extends Thread{ 方法1; 方法2; … public void run(){ // other code… } 屬性1; 屬性2; … }
先看一個簡單的例子:
?
/** * @author Rollen-Holt 繼承Thread類,直接調用run方法 * */class hello extends Thread { public hello() { } public hello(String name) { this.name = name; } public void run() { for (int i = 0; i < 5; i++) { System.out.println(name + "運行 " + i); } } public static void main(String[] args) { hello h1=new hello("A"); hello h2=new hello("B"); h1.run(); h2.run(); } private String name; }
【運行結果】:
A運行 0
A運行 1
A運行 2
A運行 3
A運行 4
B運行 0
B運行 1
B運行 2
B運行 3
B運行 4
我們會發現這些都是順序執行的,說明我們的調用方法不對,應該調用的是start()方法。
當我們把上面的主函數修改為如下所示的時候:
?
123456 public static void main(String[] args) { hello h1=new hello("A"); hello h2=new hello("B"); h1.start(); h2.start(); }
然後運行程序,輸出的可能的結果如下:
A運行 0
B運行 0
B運行 1
B運行 2
B運行 3
B運行 4
A運行 1
A運行 2
A運行 3
A運行 4
因為需要用到CPU的資源,所以每次的運行結果基本是都不一樣的,呵呵。
注意:雖然我們在這里調用的是start()方法,但是實際上調用的還是run()方法的主體。
那麼:為什麼我們不能直接調用run()方法呢?
我的理解是:線程的運行需要本地操作系統的支持。
如果你查看start的源代碼的時候,會發現:
?
1234567891011121314151617 public synchronized void start() { /** * This method is not invoked for the main method thread or "system" * group threads created/set up by the VM. Any new functionality added * to this method in the future may have to also be added to the VM. * * A zero status value corresponds to state "NEW". */ if (threadStatus != 0 || this != me) throw new IllegalThreadStateException(); group.add(this); start0(); if (stopBeforeStart) { stop0(throwableFromStop); } } private native void start0();
注意我用紅色加粗的那一條語句,說明此處調用的是start0()。並且這個這個方法用了native關鍵字,次關鍵字表示調用本地操作系統的函數。因為多線程的實現需要本地操作系統的支持。
但是start方法重復調用的話,會出現java.lang.IllegalThreadStateException異常。
通過實現Runnable介面:
大致框架是:
?
123456789101112 class 類名 implements Runnable{ 方法1; 方法2; … public void run(){ // other code… } 屬性1; 屬性2; … }
來先看一個小例子吧:
?
2930 /** * @author Rollen-Holt 實現Runnable介面 * */class hello implements Runnable { public hello() { } public hello(String name) { this.name = name; } public void run() { for (int i = 0; i < 5; i++) { System.out.println(name + "運行 " + i); } } public static void main(String[] args) { hello h1=new hello("線程A"); Thread demo= new Thread(h1); hello h2=new hello("線程B"); Thread demo1=new Thread(h2); demo.start(); demo1.start(); } private String name; }
【可能的運行結果】:
線程A運行 0
線程B運行 0
線程B運行 1
線程B運行 2
線程B運行 3
線程B運行 4
線程A運行 1
線程A運行 2
線程A運行 3
線程A運行 4
關於選擇繼承Thread還是實現Runnable介面?
其實Thread也是實現Runnable介面的:
?
12345678 class Thread implements Runnable { //… public void run() { if (target != null) { target.run(); } } }
其實Thread中的run方法調用的是Runnable介面的run方法。不知道大家發現沒有,Thread和Runnable都實現了run方法,這種操作模式其實就是代理模式。關於代理模式,我曾經寫過一個小例子呵呵,大家有興趣的話可以看一下:http://www.cnblogs.com/rollenholt/archive/2011/08/18/2144847.html
Thread和Runnable的區別:
如果一個類繼承Thread,則不適合資源共享。但是如果實現了Runable介面的話,則很容易的實現資源共享。
?
/** * @author Rollen-Holt 繼承Thread類,不能資源共享 * */class hello extends Thread { public void run() { for (int i = 0; i < 7; i++) { if (count > 0) { System.out.println("count= " + count--); } } } public static void main(String[] args) { hello h1 = new hello(); hello h2 = new hello(); hello h3 = new hello(); h1.start(); h2.start(); h3.start(); } private int count = 5; }
【運行結果】:
count= 5
count= 4
count= 3
count= 2
count= 1
count= 5
count= 4
count= 3
count= 2
count= 1
count= 5
count= 4
count= 3
count= 2
count= 1
大家可以想像,如果這個是一個買票系統的話,如果count表示的是車票的數量的話,說明並沒有實現資源的共享。
我們換為Runnable介面:
?
12345678910111213141516171819 /** * @author Rollen-Holt 繼承Thread類,不能資源共享 * */class hello implements Runnable { public void run() { for (int i = 0; i < 7; i++) { if (count > 0) { System.out.println("count= " + count--); } } } public static void main(String[] args) { hello he=new hello(); new Thread(he).start(); } private int count = 5; }
【運行結果】:
count= 5
count= 4
count= 3
count= 2
count= 1
總結一下吧:
實現Runnable介面比繼承Thread類所具有的優勢:
1):適合多個相同的程序代碼的線程去處理同一個資源
2):可以避免java中的單繼承的限制
3):增加程序的健壯性,代碼可以被多個線程共享,代碼和數據獨立。
所以,本人建議大家勁量實現介面。
?
⑵ 求《Java多線程編程核心技術(高洪岩0》全文免費下載百度網盤資源,謝謝~
《Java多線程編程核心技術(高洪岩0》網路網盤pdf最新全集下載:
鏈接: https://pan..com/s/1GzMYjd5gdh4DXDUYthmM9Q
⑶ Java多線程 Reactor模式和NIO
java nio從1.4版本就出現了,而且依它優異的性能贏得了廣大java開發愛好者的信賴。我很納悶,為啥我到現在才接觸,難道我不是愛好者,難道nio不優秀。經過長達半分鍾的思考,我意識到:時候未到。以前總是寫那些老掉牙的web程序,唉,好不容易翻身啦,現在心裡好受多了。因為真不想自己到了30歲,還在說,我會ssh,會ssi,精通javascript,精通資料庫,精通。。。人生苦短,要開拓點不是嗎?列為兄弟姐妹,沒看到外國的和尚已經開始鼓吹「雲里霧里」的?沒看到網路進入「框」啦,沒看到oracle的「格」啦。人家的經,隨他念,但是我們的確有好多路要走哦(牢騷怎麼這么多呀)。
現在終於到了我了解nio的時候了,突然發現有很多美妙程序的源碼,不得不爽一把(有邪念者,該打住啦,像我這樣)。
以下描述,為了說明問題,就提提歷史(類似的東西,網上一搜一大把,但是希望你能在這里止步,知道到底是怎麼回事。如果還是不清楚,咱就站內溝通!)。
在我(剛)看nio的這段時間里,主要接觸了幾個東西,就是關於server和client。java之前的io完全可以勝任,但是效率不高,為何效率不高呢?
===============history==start===============
//TODO:finish the old style of server and socket data transion.
ServerSocket socket = new ServerSocket(80);
while (true) {
final Socket connection = socket.accept();
handleRequest(connection);
}
===============history==end in the future================
在上面的代碼片段中,我們只能是一個request一個的進行處理。這使得所有的請求都阻塞了。如果我們再改變一下,將handleRequest方法封裝到線程中處理:
if(connection = null){
new Thread(new Runnable(){
public void run(){
handleRequest(connection);
}
public void handleRequest(Socket conn){
//do actions
}
}).start();
}
伺服器端的資源是有限的,我們這里僅僅是從線程角度來擴展,但是這種處理依然是阻塞的處理方式。首先,僅僅是建立連接(socket),就佔用了伺服器的線程資源。如果客戶端還沒有發出相應的數據請求,那麼伺服器就要一直等待他們的數據流過來,然後再進行讀取,如此往復。。。一直都blocking。伺服器處在一個高負荷狀態中。
NIO出來之後,進入改革開放時期,有了這么幾個角色,ServerSocketChannel,SelectionKey,Selector.
這幾個角色都是做什麼用的呢?需要了解一下reactor模式(反應堆模式)。
作為服務端,如果什麼操作都要依賴於客戶端,很多操作都阻塞,如上面的代碼片段所示
⑷ java 多線程是什麼
進程是程序在處理機中的一次運行。一個進程既包括其所要執行的指令,也包括了執行指令所需的系統資源,不同進程所佔用的系統資源相對獨立。所以進程是重量級的任務,它們之間的通信和轉換都需要操作系統付出較大的開銷。
線程是進程中的一個實體,是被系統獨立調度和分派的基本單位。線程自己基本上不擁有系統資源,但它可以與同屬一個進程的其他線程共享進程所擁有的全部資源。所以線程是輕量級的任務,它們之間的通信和轉換只需要較小的系統開銷。
Java支持多線程編程,因此用Java編寫的應用程序可以同時執行多個任務。Java的多線程機制使用起來非常方便,用戶只需關注程序細節的實現,而不用擔心後台的多任務系統。
Java語言里,線程表現為線程類。Thread線程類封裝了所有需要的線程操作控制。在設計程序時,必須很清晰地區分開線程對象和運行線程,可以將線程對象看作是運行線程的控制面板。在線程對象里有很多方法來控制一個線程是否運行,睡眠,掛起或停止。線程類是控制線程行為的唯一的手段。一旦一個Java程序啟動後,就已經有一個線程在運行。可通過調用Thread.currentThread方法來查看當前運行的是哪一個線程。
⑸ 在Java 中多線程的實現方法有哪些,如何使用
1、 認識Thread和Runnable
Java中實現多線程有兩種途徑:繼承Thread類或者實現Runnable介面。Runnable是介面,建議用介面的方式生成線程,因為介面可以實現多繼承,況且Runnable只有一個run方法,很適合繼承。在使用Thread的時候只需繼承Thread,並且new一個實例出來,調用start()方法即可以啟動一個線程。
Thread Test = new Thread();
Test.start();
在使用Runnable的時候需要先new一個實現Runnable的實例,之後啟動Thread即可。
Test impelements Runnable;
Test t = new Test();
Thread test = new Thread(t);
test.start();
總結:Thread和Runnable是實現java多線程的2種方式,runable是介面,thread是類,建議使用runable實現java多線程,不管如何,最終都需要通過thread.start()來使線程處於可運行狀態。
2、 認識Thread的start和run
1) start:
用start方法來啟動線程,真正實現了多線程運行,這時無需等待run方法體代碼執行完畢而直接繼續執行下面的代碼。通過調用Thread類的start()方法來啟動一個線程,這時此線程處於就緒(可運行)狀態,並沒有運行,一旦得到spu時間片,就開始執行run()方法,這里方法run()稱為線程體,它包含了要執行的這個線程的內容,Run方法運行結束,此線程隨即終止。
2) run:
run()方法只是類的一個普通方法而已,如果直接調用Run方法,程序中依然只有主線程這一個線程,其程序執行路徑還是只有一條,還是要順序執行,還是要等待run方法體執行完畢後才可繼續執行下面的代碼,這樣就沒有達到寫線程的目的。
總結:調用start方法方可啟動線程,而run方法只是thread的一個普通方法調用,還是在主線程里執行。
3、 線程狀態說明
線程狀態從大的方面來說,可歸結為:初始狀態、可運行狀態、不可運行狀態和消亡狀態,具體可細分為上圖所示7個狀態,說明如下:
1) 線程的實現有兩種方式,一是繼承Thread類,二是實現Runnable介面,但不管怎樣,當我們new了thread實例後,線程就進入了初始狀態;
2) 當該對象調用了start()方法,就進入可運行狀態;
3) 進入可運行狀態後,當該對象被操作系統選中,獲得CPU時間片就會進入運行狀態;
4) 進入運行狀態後case就比較多,大致有如下情形:
·run()方法或main()方法結束後,線程就進入終止狀態;
·當線程調用了自身的sleep()方法或其他線程的join()方法,就會進入阻塞狀態(該狀態既停止當前線程,但並不釋放所佔有的資源)。當sleep()結束或join()結束後,該線程進入可運行狀態,繼續等待OS分配時間片;
·當線程剛進入可運行狀態(注意,還沒運行),發現將要調用的資源被鎖牢(synchroniza,lock),將會立即進入鎖池狀態,等待獲取鎖標記(這時的鎖池裡也許已經有了其他線程在等待獲取鎖標記,這時它們處於隊列狀態,既先到先得),一旦線程獲得鎖標記後,就轉入可運行狀態,等待OS分配CPU時間片;
·當線程調用wait()方法後會進入等待隊列(進入這個狀態會釋放所佔有的所有資源,與阻塞狀態不同),進入這個狀態後,是不能自動喚醒的,必須依靠其他線程調用notify()或notifyAll()方法才能被喚醒(由於notify()只是喚醒一個線程,但我們由不能確定具體喚醒的是哪一個線程,也許我們需要喚醒的線程不能夠被喚醒,因此在實際使用時,一般都用notifyAll()方法,喚醒有所線程),線程被喚醒後會進入鎖池,等待獲取鎖標記。
·當線程調用stop方法,即可使線程進入消亡狀態,但是由於stop方法是不安全的,不鼓勵使用,大家可以通過run方法里的條件變通實現線程的stop。
⑹ 《Java線程與並發編程實踐》pdf下載在線閱讀全文,求百度網盤雲資源
《Java線程與並發編程實踐》網路網盤pdf最新全集下載:
鏈接: https://pan..com/s/1zebgAWKpIEWptv9zB_Y2GA
⑺ java與模式 pdf電子書(高清版)
Java與模式清晰完整版
現在還能下
http://www.shubulo.com/viewthread.php?tid=29221
⑻ 《Java並發編程實戰》pdf下載在線閱讀,求百度網盤雲資源
《Java並發編程實戰》(Brian Goetz)電子書網盤下載免費在線閱讀
鏈接:https://pan..com/s/1LkHQ1LOcgxHjCxplxfhmSg提取碼:1234
書名:Java並發編程實戰
作者:Brian Goetz
譯者:童雲蘭
豆瓣評分:9.0
出版社:機械工業出版社華章公司
出版年份:2012-2
頁數:293
內容簡介:
本書深入淺出地介紹了Java線程和並發,是一本完美的Java並發參考手冊。書中從並發性和線程安全性的基本概念出發,介紹了如何使用類庫提供的基本並發構建塊,用於避免並發危險、構造線程安全的類及驗證線程安全的規則,如何將小的線程安全類組合成更大的線程安全類,如何利用線程來提高並發應用程序的吞吐量,如何識別可並行執行的任務,如何提高單線程子系統的響應性,如何確保並發程序執行預期任務,如何提高並發代碼的性能和可伸縮性等內容,最後介紹了一些高級主題,如顯式鎖、原子變數、非阻塞演算法以及如何開發自定義的同步工具類。
本書適合Java程序開發人員閱讀。
作者簡介:
本書作者都是Java Community Process JSR 166專家組(並發工具)的主要成員,並在其他很多JCP專家組里任職。Brian Goetz有20多年的軟體咨詢行業經驗,並著有至少75篇關於Java開發的文章。Tim Peierls是「現代多處理器」的典範,他在BoxPop.biz、唱片藝術和戲劇表演方面也頗有研究。Joseph Bowbeer是一個Java ME專家,他對並發編程的興趣始於Apollo計算機時代。David Holmes是《The Java Programming Language》一書的合著者,任職於Sun公司。Joshua Bloch是Google公司的首席Java架構師,《Effective Java》一書的作者,並參與著作了《Java Puzzlers》。Doug Lea是《Concurrent Programming》一書的作者,紐約州立大學 Oswego分校的計算機科學教授。
⑼ java中什麼叫做線程什麼叫多線程多線程的特點是什麼
線程的概念:Thread 每個正在系統上運行的程序都是一個進程。每個進程包含一到多個線程。進程也可能是整個程序或者是部分程序的動態執行。
多線程的概念: 多線程是為了同步完成多項任務,不是為了提高運行效率,而是為了提高資源使用效率來提高系統的效率。
多線程的特點:使用線程可以把占據長時間的程序中的任務放到後台去處理
用戶界面可以更加吸引人,這樣比如用戶點擊了一個按鈕去觸發某些事件的處理,可以彈出一個進度條來顯示處理的進度 。
程序的運行速度可能加快 ·在一些等待的任務實現上如用戶輸入、文件讀寫和網路收發數據等,線程就比較有用了。
在這種情況下我們可以釋放一些珍貴的資源如內存佔用等等。
⑽ 《Java多線程編程實戰指南(核心篇)》epub下載在線閱讀,求百度網盤雲資源
《Java多線程編程實戰指南(核心篇)》(黃文海)電子書網盤下載免費在線閱讀
資源鏈接:
鏈接:https://pan..com/s/1ZuTI8tfjbzyOip5krhPxqg
書名:Java多線程編程實戰指南(核心篇)
作者:黃文海
豆瓣評分:9.0
出版社:電子工業出版社
出版年份:2017-4
頁數:480
內容簡介:隨著現代處理器的生產工藝從提升處理器主頻頻率轉向多核化,即在一塊晶元上集成多個處理器內核(Core),多核處理器(Multicore Processor)離我們越來越近了——如今就連智能手機這樣的消費類設備都已配備了4核乃至8核的處理器,更何況商用系統!在此背景下,以往靠單個處理器自身處理能力的提升所帶來的軟體計算性能提升的那種「免費午餐」已不復存在,這使得多線程編程在充分利用計算資源、提高軟體服務質量方面扮演了越來越重要的角色。故而,掌握多線程編程技能對廣大開發人員的重要性亦由此可見一斑。《Java多線程編程實戰指南(核心篇)》以基本概念、原理與方法為主線,輔以豐富的實戰案例和生活化實例,並從Java虛擬機、操作系統和硬體多個層次與角度出發,循序漸進、系統地介紹Java平台下的多線程編程核心技術及相關工具。
《Java多線程編程實戰指南(核心篇)》適合有一定Java語言基礎的讀者作為入門多線程編程之用,也適合有一定多線程編程經驗的讀者作為重新梳理知識結構以提升認知層次和參考之用。