第一篇:Java編程學(xué)習(xí)順序
1.第一階段 掌握要點(diǎn):Java語(yǔ)基礎(chǔ)知識(shí)。包括異常、IO流、多線程、集合類、數(shù)據(jù)庫(kù)。
(切記基礎(chǔ)知識(shí)一定要時(shí)時(shí)刻刻鞏固)eg:Java編程思想、Java2 核心技術(shù)
2.第二階段掌握要點(diǎn):Tomcat,毋庸置疑,Tomcat為學(xué)習(xí)web服務(wù)首選。而應(yīng)用服務(wù)器
目前主要有:jboss , weblogic.websphere.而Tomcat和jboss是首選。
3.第三階段掌握要點(diǎn):Java網(wǎng)絡(luò)編程。包括:SocketRMLHTMLJSPJavaBean
Servlet.開(kāi)發(fā)工具:Myeclipsedreamweaver順序:
1、學(xué)習(xí)web 知識(shí):htmldreamwavejavascript2、先學(xué)習(xí)jsp設(shè)計(jì)、Javaservlet編程
3、學(xué)習(xí)jdbc數(shù)據(jù)庫(kù)編程
4、學(xué)習(xí),他和學(xué)習(xí)ejb可以結(jié)合起來(lái)《《精通ejb》》學(xué)習(xí)ejb設(shè)計(jì)模式和看代碼(最重要)《jsp2.0 技術(shù)手冊(cè)》 在jsp上不要花太多時(shí)間,在時(shí)間放在servlet多一些
4.第四階段 掌握要點(diǎn):流行MVC 架構(gòu)和Java對(duì)象持久化技術(shù)。包括struts
SpringHibernate JSF.學(xué)習(xí)過(guò)程:先學(xué)Struts,再學(xué)習(xí)Hibernate,最后學(xué)習(xí)Spring
第二篇:JAVA學(xué)習(xí)順序
第一部分:J2se學(xué)習(xí)視頻內(nèi)容包括: JAVA視頻教程_J2SE_5.0_專題_日期處理 JAVA視頻教程_J2SE_專題_正則表達(dá)式 反射avi
第二部分:j2se練習(xí)項(xiàng)目視頻內(nèi)容包括: 尚學(xué)堂科技_馬士兵_在線聊天系統(tǒng)雛形視頻教程_java_eclipse
尚學(xué)堂科技_馬士兵_坦克大戰(zhàn)視頻教程_java_eclipse
尚學(xué)堂科技_馬士兵_坦克大戰(zhàn)圖片版
尚學(xué)堂科技_馬士兵_JAVA_坦克大戰(zhàn)網(wǎng)絡(luò)版視頻教程
尚學(xué)堂科技_馬士兵_snake_貪吃蛇內(nèi)部視頻
第三部分?jǐn)?shù)據(jù)庫(kù)視頻
Oracle視頻內(nèi)容包括:01——53講avi格式
第四部分:JDBC和MySQL視頻,內(nèi)容包括: 1_lomboz_eclipse_jdbc 2_mysql_avi
3_連接池的設(shè)計(jì)思路.avi
第五部分:HTML & CSS & JAVASCRIPT 視頻: Html & CSS 視頻內(nèi)容簡(jiǎn)介:
01_html簡(jiǎn)單介紹和meta標(biāo)簽.avi 02_a_路徑問(wèn)題等等.avi
03_學(xué)習(xí)方法_其他常用標(biāo)簽.avi 04_1_note.avi
04_表格和表單_1.avi 05_表格和表單_2.avi 06_Frame.avi
07_Dreamweaver.avi 08_CSS_1.avi
09_CSS_2_選擇方式.avi 10_CSS_3.avi 11_CSS_4.avi
JavaScript 視頻簡(jiǎn)介: 01_JS初步及調(diào)試.avi 02_JS基本語(yǔ)法.avi
03_函數(shù)_事件處理_1.avi 04_事件處理_2.avi
05_內(nèi)置對(duì)象_DOM_BOM.avi 06_趣味.avi 07_實(shí)用.avi 08_表單驗(yàn)證.avi 09_表單驗(yàn)證_new.avi 10_后臺(tái)框架.avi 11_后臺(tái)框架_2.avi 12_TREE.avi
第六部分:Servlet & JSP視頻——內(nèi)容包括:tomcat的安裝使用,配置servlet & jsp 視頻 1——30節(jié) jsp的練習(xí)項(xiàng)目?jī)?nèi)容包括: 3 簡(jiǎn)單bbs項(xiàng)目2007美化BBS項(xiàng)目 4 網(wǎng)上商城項(xiàng)目視頻網(wǎng)上商城項(xiàng)目視頻講解視頻
第七部分:J2EE學(xué)習(xí)視頻包括: DRP項(xiàng)目
框架視頻學(xué)習(xí): Struts視頻 Hibernate視頻 Spring視頻 提高部分:
uml統(tǒng)一建模語(yǔ)言視頻 SSH項(xiàng)目視頻:
oa辦公自動(dòng)化系統(tǒng)視頻 crm項(xiàng)目視頻 銀行系統(tǒng)視頻 ejb3.0視頻
J2ME_3G簡(jiǎn)介資料 面試材料:
面試題大匯總+筆記+技巧
第三篇:JAVA編程心得體會(huì)
JAVA編程心得
計(jì)算機(jī)3班
竇金霞
20104773
最近幾周一直在弄程序,說(shuō)實(shí)話真的很累,但累中也有成功的快樂(lè)。我覺(jué)得學(xué)到了很多東西,這是只看課本知識(shí)所不能學(xué)到的。
說(shuō)實(shí)話,以前我一直沒(méi)學(xué)過(guò)JAVA雖然我也知道JAVA的重要性,可是即使上課聽(tīng)了,不實(shí)踐還是掌握不了。因?yàn)榉N種原因,今年我沒(méi)有買筆記本。沒(méi)有機(jī)器,僅僅靠每周一次的上機(jī)練習(xí)是絕對(duì)不夠的。所以我就插空調(diào)程序,在舍友們不用的時(shí)候自己再接她們的電腦調(diào)。
調(diào)上一個(gè)WEB版的通訊錄程序時(shí)我已經(jīng)感覺(jué)到學(xué)的很吃力,好多東西都不懂。這次做的這個(gè)學(xué)生成績(jī)管理系統(tǒng)更復(fù)雜了,所以一開(kāi)始調(diào)的時(shí)候感覺(jué)特別吃力.所以我告訴自己不能放棄,慢慢來(lái),就這樣我從最基本的sql語(yǔ)句session對(duì)象開(kāi)始學(xué)起,我覺(jué)得我還有太多不懂得所以要比別人付出更多的努力。就這樣我一點(diǎn)一點(diǎn)的學(xué)著??
說(shuō)心里話,在做上一個(gè)web版的通訊錄時(shí),我就感覺(jué)到成功的喜悅。好多地方我都是一點(diǎn)一點(diǎn)的問(wèn)的,在問(wèn)的過(guò)程中,我也學(xué)會(huì)了很多,像:Servlet和jsp之間跳不過(guò)去時(shí)有兩種解決辦法,一是關(guān)閉底層類中的db.close;二是將Servlet中的throws Exception改成try catch以捕捉異常;我還學(xué)到了集中查找錯(cuò)誤的方法,可以加上兩個(gè)雙斜杠“//”將具體的方法屏蔽掉,一檢查是方法錯(cuò)誤還是Servlet錯(cuò)誤,還有就是寫(xiě)上System.out.println()將獲得的數(shù)據(jù)輸出,用來(lái)檢查數(shù)據(jù)傳輸過(guò)程有沒(méi)有錯(cuò)誤等等。
雖然在別人看來(lái),這些方法可能都很常規(guī),但是確實(shí)我自己學(xué)會(huì)的,我覺(jué)得很有成就感。我已經(jīng)做好計(jì)劃了,暑假的時(shí)候去買本本用自己的本本練習(xí)一下JAVA,雖然下學(xué)期不學(xué)JAVA了,但是我對(duì)JAVA的熱情不會(huì)因?yàn)檫@個(gè)而削減的!
做完這個(gè)學(xué)生成績(jī)管理系統(tǒng)后,我覺(jué)得我對(duì)JAVA的看法已經(jīng)改變了。一前總以為JAVA很繁瑣很難,聽(tīng)同學(xué)說(shuō)JAVA不好學(xué),開(kāi)始又有一些聽(tīng)不懂,所以一直很畏懼JAVA。但真正做了這個(gè)系統(tǒng)以后我才感覺(jué)到其實(shí)任何事都沒(méi)有難與不難之分,只要你肯努力的去做,世上無(wú)難事只怕有心人!
我現(xiàn)在對(duì)java學(xué)習(xí)充滿了熱情,我知道我還有很多的不足
還有很多需要努力的地方,所以我的JAVA之旅將繼續(xù)進(jìn)行??
第四篇:學(xué)習(xí)Java編程,就只能做Java程序員嗎?
學(xué)習(xí)Java編程,就只能做Java程序員嗎?
作為世界上使用最廣的語(yǔ)言之一,Java 的擁躉和其他語(yǔ)言的粉絲常常在各大論壇掀起世界大戰(zhàn)。
Java 說(shuō)『Write Once,Run Anywhere』
但還有人說(shuō) 『Write Once,Debug Anywhere』
有人說(shuō)他語(yǔ)法簡(jiǎn)單,功能強(qiáng)大。
可也有人說(shuō)與許多新興語(yǔ)言相比,他有些細(xì)節(jié)上的不足。
所以,Java 對(duì)你來(lái)說(shuō)究竟是什么?
你可曾想過(guò),學(xué)習(xí)Java編程之后,你就只能做Java程序員嗎?其實(shí)。。
學(xué)習(xí)Java編程可以往很多方向發(fā)展
Java的應(yīng)用非常廣,有erp等大型系統(tǒng)方面的,有web方面的,還有游戲方面的。作為小白,你需要從Java初級(jí)學(xué),然后中級(jí),之后你還需要再學(xué)習(xí)更多的技術(shù),這些技術(shù)不僅僅局限于Java,如js和數(shù)據(jù)庫(kù)等,當(dāng)你對(duì)整套技術(shù)都非常精通時(shí),你便是一個(gè)真正的高級(jí)工程師,而java則只是你所掌握的主要技術(shù)之一罷了。
做軟件測(cè)試是一個(gè)方向
不少人學(xué)到Java SE基礎(chǔ)階段,可能往軟件測(cè)試方向發(fā)展,這個(gè)時(shí)候參與具體的編碼工作不會(huì)那么多,主要要做的工作是對(duì)軟件產(chǎn)品的需求文檔、設(shè)計(jì)文檔等檢查是否有歧義,對(duì)軟件產(chǎn)品本身的功能、性能通過(guò)運(yùn)用專業(yè)的軟件測(cè)試技術(shù)以及工作去發(fā)現(xiàn)軟件產(chǎn)品中隱藏的軟件問(wèn)題。
轉(zhuǎn)Android開(kāi)發(fā)是一個(gè)方向
Android是主流智能手機(jī)的操作系統(tǒng),Java是一種開(kāi)發(fā)語(yǔ)言,兩者沒(méi)有好壞優(yōu)劣之分,只是兩種職業(yè)崗位的選擇。學(xué)Android從事移動(dòng)互聯(lián)方向開(kāi)發(fā),學(xué)Java從事軟件、網(wǎng)站開(kāi)發(fā)。而安卓上的應(yīng)用大多是Java編寫(xiě)的,所以學(xué)習(xí)了Java編程,轉(zhuǎn)Android開(kāi)發(fā)也是可以的。
轉(zhuǎn)web前端開(kāi)發(fā)、PHP開(kāi)發(fā)、大數(shù)據(jù)。。
其實(shí),Java對(duì)你來(lái)說(shuō),不過(guò)是眾多戀人之一,作為初戀,她打開(kāi)了你學(xué)習(xí)編程的大門。至于以后你是從事前端開(kāi)發(fā),或PHP開(kāi)發(fā),亦或Android開(kāi)發(fā),甚至搞大數(shù)據(jù)、數(shù)據(jù)庫(kù),這些都是互不干擾的。
你的程序猿生涯,從踹開(kāi)Java大門開(kāi)始 圍觀知了堂Java大咖竹邇【提神的咖啡】
第五篇:Java多線程編程總結(jié)
Java多線程編程總結(jié)
2007-05-17 11:21:59 標(biāo)簽:java 多線程
原創(chuàng)作品,允許轉(zhuǎn)載,轉(zhuǎn)載時(shí)請(qǐng)務(wù)必以超鏈接形式標(biāo)明文章 原始出處、作者信息和本聲明。否則將追究法律責(zé)任。http://lavasoft.blog.51cto.com/62575/27069
Java多線程編程總結(jié)
下面是Java線程系列博文的一個(gè)編目:
Java線程:概念與原理 Java線程:創(chuàng)建與啟動(dòng)
Java線程:線程棧模型與線程的變量 Java線程:線程狀態(tài)的轉(zhuǎn)換 Java線程:線程的同步與鎖 Java線程:線程的交互 Java線程:線程的調(diào)度-休眠 Java線程:線程的調(diào)度-優(yōu)先級(jí) Java線程:線程的調(diào)度-讓步 Java線程:線程的調(diào)度-合并 Java線程:線程的調(diào)度-守護(hù)線程 Java線程:線程的同步-同步方法 Java線程:線程的同步-同步塊
Java線程:并發(fā)協(xié)作-生產(chǎn)者消費(fèi)者模型 Java線程:并發(fā)協(xié)作-死鎖 Java線程:volatile關(guān)鍵字 Java線程:新特征-線程池
Java線程:新特征-有返回值的線程 Java線程:新特征-鎖(上)Java線程:新特征-鎖(下)Java線程:新特征-信號(hào)量 Java線程:新特征-阻塞隊(duì)列 Java線程:新特征-阻塞棧 Java線程:新特征-條件變量 Java線程:新特征-原子量 Java線程:新特征-障礙器 Java線程:大總結(jié)
----
下面的內(nèi)容是很早之前寫(xiě)的,內(nèi)容不夠充實(shí),而且是基于Java1.4的內(nèi)容,Java5之后,線程并發(fā)部分?jǐn)U展了相當(dāng)多的內(nèi)容,因此建議大家看上面的系列文章的內(nèi)容,與時(shí)俱進(jìn),跟上Java發(fā)展的步伐。----
一、認(rèn)識(shí)多任務(wù)、多進(jìn)程、單線程、多線程 要認(rèn)識(shí)多線程就要從操作系統(tǒng)的原理說(shuō)起。
以前古老的DOS操作系統(tǒng)(V 6.22)是單任務(wù)的,還沒(méi)有線程的概念,系統(tǒng)在每次只能做一件事情。比如你在copy東西的時(shí)候不能rename文件名。為了提高系統(tǒng)的利用效率,采用批處理來(lái)批量執(zhí)行任務(wù)。
現(xiàn)在的操作系統(tǒng)都是多任務(wù)操作系統(tǒng),每個(gè)運(yùn)行的任務(wù)就是操作系統(tǒng)所做的一件事情,比如你在聽(tīng)歌的同時(shí)還在用MSN和好友聊天。聽(tīng)歌和聊天就是兩個(gè)任務(wù),這個(gè)兩個(gè)任務(wù)是“同時(shí)”進(jìn)行的。一個(gè)任務(wù)一般對(duì)應(yīng)一個(gè)進(jìn)程,也可能包含好幾個(gè)進(jìn)程。比如運(yùn)行的MSN就對(duì)應(yīng)一個(gè)MSN的進(jìn)程,如果你用的是windows系統(tǒng),你就可以在任務(wù)管理器中看到操作系統(tǒng)正在運(yùn)行的進(jìn)程信息。
一般來(lái)說(shuō),當(dāng)運(yùn)行一個(gè)應(yīng)用程序的時(shí)候,就啟動(dòng)了一個(gè)進(jìn)程,當(dāng)然有些會(huì)啟動(dòng)多個(gè)進(jìn)程。啟動(dòng)進(jìn)程的時(shí)候,操作系統(tǒng)會(huì)為進(jìn)程分配資源,其中最主要的資源是內(nèi)存空間,因?yàn)槌绦蚴窃趦?nèi)存中運(yùn)行的。在進(jìn)程中,有些程序流程塊是可以亂序執(zhí)行的,并且這個(gè)代碼塊可以同時(shí)被多次執(zhí)行。實(shí)際上,這樣的代碼塊就是線程體。線程是進(jìn)程中亂序執(zhí)行的代碼流程。當(dāng)多個(gè)線程同時(shí)運(yùn)行的時(shí)候,這樣的執(zhí)行模式成為并發(fā)執(zhí)行。
多線程的目的是為了最大限度的利用CPU資源。
Java編寫(xiě)程序都運(yùn)行在在Java虛擬機(jī)(JVM)中,在JVM的內(nèi)部,程序的多任務(wù)是通過(guò)線程來(lái)實(shí)現(xiàn)的。每用java命令啟動(dòng)一個(gè)java應(yīng)用程序,就會(huì)啟動(dòng)一個(gè)JVM進(jìn)程。在同一個(gè)JVM進(jìn)程中,有且只有一個(gè)進(jìn)程,就是它自己。在這個(gè)JVM環(huán)境中,所有程序代碼的運(yùn)行都是以線程來(lái)運(yùn)行。
一般常見(jiàn)的Java應(yīng)用程序都是單線程的。比如,用java命令運(yùn)行一個(gè)最簡(jiǎn)單的HelloWorld的Java應(yīng)用程序時(shí),就啟動(dòng)了一個(gè)JVM進(jìn)程,JVM找到程序程序的入口點(diǎn)main(),然后運(yùn)行main()方法,這樣就產(chǎn)生了一個(gè)線程,這個(gè)線程稱之為主線程。當(dāng)main方法結(jié)束后,主線程運(yùn)行完成。JVM進(jìn)程也隨即退出。
對(duì)于一個(gè)進(jìn)程中的多個(gè)線程來(lái)說(shuō),多個(gè)線程共享進(jìn)程的內(nèi)存塊,當(dāng)有新的線程產(chǎn)生的時(shí)候,操作系統(tǒng)不分配新的內(nèi)存,而是讓新線程共享原有的進(jìn)程塊的內(nèi)存。因此,線程間的通信很容易,速度也很快。不同的進(jìn)程因?yàn)樘幱诓煌膬?nèi)存塊,因此進(jìn)程之間的通信相對(duì)困難。
實(shí)際上,操作的系統(tǒng)的多進(jìn)程實(shí)現(xiàn)了多任務(wù)并發(fā)執(zhí)行,程序的多線程實(shí)現(xiàn)了進(jìn)程的并發(fā)執(zhí)行。多任務(wù)、多進(jìn)程、多線程的前提都是要求操作系統(tǒng)提供多任務(wù)、多進(jìn)程、多線程的支持。
在Java程序中,JVM負(fù)責(zé)線程的調(diào)度。線程調(diào)度是值按照特定的機(jī)制為多個(gè)線程分配CPU的使用權(quán)。調(diào)度的模式有兩種:分時(shí)調(diào)度和搶占式調(diào)度。分時(shí)調(diào)度是所有線程輪流獲得CPU使用權(quán),并平均分配每個(gè)線程占用CPU的時(shí)間;搶占式調(diào)度是根據(jù)線程的優(yōu)先級(jí)別來(lái)獲取CPU的使用權(quán)。JVM的線程調(diào)度模式采用了搶占式模式。
所謂的“并發(fā)執(zhí)行”、“同時(shí)”其實(shí)都不是真正意義上的“同時(shí)”。眾所周知,CPU都有個(gè)時(shí)鐘頻率,表示每秒中能執(zhí)行cpu指令的次數(shù)。在每個(gè)時(shí)鐘周期內(nèi),CPU實(shí)際上只能去執(zhí)行一條(也有可能多條)指令。操作系統(tǒng)將進(jìn)程線程進(jìn)行管理,輪流(沒(méi)有固定的順序)分配每個(gè)進(jìn)程很短的一段是時(shí)間(不一定是均分),然后在每個(gè)線程內(nèi)部,程序代碼自己處理該進(jìn)程內(nèi)部線程的時(shí)間分配,多個(gè)線程之間相互的切換去執(zhí)行,這個(gè)切換時(shí)間也是非常短的。因此多任務(wù)、多進(jìn)程、多線程都是操作系統(tǒng)給人的一種宏觀感受,從微觀角度看,程序的運(yùn)行是異步執(zhí)行的。
用一句話做總結(jié):雖然操作系統(tǒng)是多線程的,但CPU每一時(shí)刻只能做一件事,和人的大腦是一樣的,呵呵。
二、Java與多線程
Java語(yǔ)言的多線程需要操作系統(tǒng)的支持。
Java 虛擬機(jī)允許應(yīng)用程序并發(fā)地運(yùn)行多個(gè)執(zhí)行線程。Java語(yǔ)言提供了多線程編程的擴(kuò)展點(diǎn),并給出了功能強(qiáng)大的線程控制API。
在Java中,多線程的實(shí)現(xiàn)有兩種方式: 擴(kuò)展java.lang.Thread類 實(shí)現(xiàn)java.lang.Runnable接口
每個(gè)線程都有一個(gè)優(yōu)先級(jí),高優(yōu)先級(jí)線程的執(zhí)行優(yōu)先于低優(yōu)先級(jí)線程。每個(gè)線程都可以或不可以標(biāo)記為一個(gè)守護(hù)程序。當(dāng)某個(gè)線程中運(yùn)行的代碼創(chuàng)建一個(gè)新 Thread 對(duì)象時(shí),該新線程的初始優(yōu)先級(jí)被設(shè)定為創(chuàng)建線程的優(yōu)先級(jí),并且當(dāng)且僅當(dāng)創(chuàng)建線程是守護(hù)線程時(shí),新線程才是守護(hù)程序。
當(dāng) Java 虛擬機(jī)啟動(dòng)時(shí),通常都會(huì)有單個(gè)非守護(hù)線程(它通常會(huì)調(diào)用某個(gè)指定類的 main 方法)。Java 虛擬機(jī)會(huì)繼續(xù)執(zhí)行線程,直到下列任一情況出現(xiàn)時(shí)為止:
調(diào)用了 Runtime 類的 exit 方法,并且安全管理器允許退出操作發(fā)生。
非守護(hù)線程的所有線程都已停止運(yùn)行,無(wú)論是通過(guò)從對(duì) run 方法的調(diào)用中返回,還是通過(guò)拋出一個(gè)傳播到 run 方法之外的異常。
三、擴(kuò)展java.lang.Thread類
/** * File Name: TestMitiThread.java * Created by: IntelliJ IDEA.* Copyright: Copyright(c)2003-2006 * Company: Lavasoft([url]http://lavasoft.blog.51cto.com/[/url])* Author: leizhimin * Modifier: leizhimin * Date Time: 2007-5-17 10:03:12 * Readme: 通過(guò)擴(kuò)展Thread類實(shí)現(xiàn)多線程 */ public class TestMitiThread { public static void main(String[] rags){ System.out.println(Thread.currentThread().getName()+ “ 線程運(yùn)行開(kāi)始!”);new MitiSay(“A”).start();new MitiSay(“B”).start();System.out.println(Thread.currentThread().getName()+ “ 線程運(yùn)行結(jié)束!”);} }
class MitiSay extends Thread { public MitiSay(String threadName){ super(threadName);}
public void run(){ System.out.println(getName()+ “ 線程運(yùn)行開(kāi)始!”);for(int i = 0;i < 10;i++){ System.out.println(i + “ ” + getName());try { sleep((int)Math.random()* 10);} catch(InterruptedException e){ e.printStackTrace();} } System.out.println(getName()+ “ 線程運(yùn)行結(jié)束!”);} }
運(yùn)行結(jié)果:
main 線程運(yùn)行開(kāi)始!main 線程運(yùn)行結(jié)束!A 線程運(yùn)行開(kāi)始!0 A 1 A B 線程運(yùn)行開(kāi)始!2 A 0 B 3 A 4 A 1 B 5 A 6 A 7 A 8 A 9 A A 線程運(yùn)行結(jié)束!2 B 3 B 4 B 5 B 6 B 7 B 8 B 9 B B 線程運(yùn)行結(jié)束!說(shuō)明:
程序啟動(dòng)運(yùn)行main時(shí)候,java虛擬機(jī)啟動(dòng)一個(gè)進(jìn)程,主線程main在main()調(diào)用時(shí)候被創(chuàng)建。隨著調(diào)用MitiSay的兩個(gè)對(duì)象的start方法,另外兩個(gè)線程也啟動(dòng)了,這樣,整個(gè)應(yīng)用就在多線程下運(yùn)行。
在一個(gè)方法中調(diào)用Thread.currentThread().getName()方法,可以獲取當(dāng)前線程的名字。在mian方法中調(diào)用該方法,獲取的是主線程的名字。
注意:start()方法的調(diào)用后并不是立即執(zhí)行多線程代碼,而是使得該線程變?yōu)榭蛇\(yùn)行態(tài)(Runnable),什么時(shí)候運(yùn)行是由操作系統(tǒng)決定的。
從程序運(yùn)行的結(jié)果可以發(fā)現(xiàn),多線程程序是亂序執(zhí)行。因此,只有亂序執(zhí)行的代碼才有必要設(shè)計(jì)為多線程。
Thread.sleep()方法調(diào)用目的是不讓當(dāng)前線程獨(dú)自霸占該進(jìn)程所獲取的CPU資源,以留出一定時(shí)間給其他線程執(zhí)行的機(jī)會(huì)。
實(shí)際上所有的多線程代碼執(zhí)行順序都是不確定的,每次執(zhí)行的結(jié)果都是隨機(jī)的。
四、實(shí)現(xiàn)java.lang.Runnable接口
/** * 通過(guò)實(shí)現(xiàn) Runnable 接口實(shí)現(xiàn)多線程 */ public class TestMitiThread1 implements Runnable {
public static void main(String[] args){ System.out.println(Thread.currentThread().getName()+ “ 線程運(yùn)行開(kāi)始!”);TestMitiThread1 test = new TestMitiThread1();Thread thread1 = new Thread(test);Thread thread2 = new Thread(test);thread1.start();thread2.start();System.out.println(Thread.currentThread().getName()+ “ 線程運(yùn)行結(jié)束!”);}
public void run(){ System.out.println(Thread.currentThread().getName()+ “ 線程運(yùn)行開(kāi)始!”);for(int i = 0;i < 10;i++){ System.out.println(i + “ ” + Thread.currentThread().getName());try { Thread.sleep((int)Math.random()* 10);} catch(InterruptedException e){ e.printStackTrace();} } System.out.println(Thread.currentThread().getName()+ “ 線程運(yùn)行結(jié)束!”);} }
運(yùn)行結(jié)果:
main 線程運(yùn)行開(kāi)始!Thread-0 線程運(yùn)行開(kāi)始!main 線程運(yùn)行結(jié)束!0 Thread-0 Thread-1 線程運(yùn)行開(kāi)始!0 Thread-1 1 Thread-1 1 Thread-0 2 Thread-0 2 Thread-1 3 Thread-0 3 Thread-1 4 Thread-0 4 Thread-1 5 Thread-0 6 Thread-0 5 Thread-1 7 Thread-0 8 Thread-0 6 Thread-1 9 Thread-0 7 Thread-1 Thread-0 線程運(yùn)行結(jié)束!8 Thread-1 9 Thread-1 Thread-1 線程運(yùn)行結(jié)束!說(shuō)明:
TestMitiThread1類通過(guò)實(shí)現(xiàn)Runnable接口,使得該類有了多線程類的特征。run()方法是多線程程序的一個(gè)約定。所有的多線程代碼都在run方法里面。Thread類實(shí)際上也是實(shí)現(xiàn)了Runnable接口的類。
在啟動(dòng)的多線程的時(shí)候,需要先通過(guò)Thread類的構(gòu)造方法Thread(Runnable target)構(gòu)造出對(duì)象,然后調(diào)用Thread對(duì)象的start()方法來(lái)運(yùn)行多線程代碼。
實(shí)際上所有的多線程代碼都是通過(guò)運(yùn)行Thread的start()方法來(lái)運(yùn)行的。因此,不管是擴(kuò)展Thread類還是實(shí)現(xiàn)Runnable接口來(lái)實(shí)現(xiàn)多線程,最終還是通過(guò)Thread的對(duì)象的API來(lái)控制線程的,熟悉Thread類的API是進(jìn)行多線程編程的基礎(chǔ)。
五、讀解Thread類API
static int MAX_PRIORITY 線程可以具有的最高優(yōu)先級(jí)。static int MIN_PRIORITY 線程可以具有的最低優(yōu)先級(jí)。static int NORM_PRIORITY 分配給線程的默認(rèn)優(yōu)先級(jí)。
構(gòu)造方法摘要
Thread(Runnable target)分配新的 Thread 對(duì)象。Thread(String name)分配新的 Thread 對(duì)象。
方法摘要
static Thread currentThread()返回對(duì)當(dāng)前正在執(zhí)行的線程對(duì)象的引用。ClassLoader getContextClassLoader()返回該線程的上下文 ClassLoader。long getId()返回該線程的標(biāo)識(shí)符。String getName()返回該線程的名稱。int getPriority()返回線程的優(yōu)先級(jí)。Thread.State getState()返回該線程的狀態(tài)。ThreadGroup getThreadGroup()返回該線程所屬的線程組。static boolean holdsLock(Object obj)當(dāng)且僅當(dāng)當(dāng)前線程在指定的對(duì)象上保持監(jiān)視器鎖時(shí),才返回 true。void interrupt()中斷線程。
static boolean interrupted()測(cè)試當(dāng)前線程是否已經(jīng)中斷。boolean isAlive()測(cè)試線程是否處于活動(dòng)狀態(tài)。boolean isDaemon()測(cè)試該線程是否為守護(hù)線程。boolean isInterrupted()測(cè)試線程是否已經(jīng)中斷。void join()等待該線程終止。void join(long millis)等待該線程終止的時(shí)間最長(zhǎng)為 millis 毫秒。void join(long millis, int nanos)等待該線程終止的時(shí)間最長(zhǎng)為 millis 毫秒 + nanos 納秒。void resume()已過(guò)時(shí)。該方法只與 suspend()一起使用,但 suspend()已經(jīng)遭到反對(duì),因?yàn)樗哂兴梨i傾向。有關(guān)更多信息,請(qǐng)參閱為何 Thread.stop、Thread.suspend 和 Thread.resume 遭到反對(duì)?。void run()如果該線程是使用獨(dú)立的 Runnable 運(yùn)行對(duì)象構(gòu)造的,則調(diào)用該 Runnable 對(duì)象的 run 方法;否則,該方法不執(zhí)行任何操作并返回。void setContextClassLoader(ClassLoader cl)設(shè)置該線程的上下文 ClassLoader。void setDaemon(boolean on)將該線程標(biāo)記為守護(hù)線程或用戶線程。
static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)設(shè)置當(dāng)線程由于未捕獲到異常而突然終止,并且沒(méi)有為該線程定義其他處理程序時(shí)所調(diào)用的默認(rèn)處理程序。void setName(String name)改變線程名稱,使之與參數(shù) name 相同。void setPriority(int newPriority)更改線程的優(yōu)先級(jí)。
void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)設(shè)置該線程由于未捕獲到異常而突然終止時(shí)調(diào)用的處理程序。static void sleep(long millis)在指定的毫秒數(shù)內(nèi)讓當(dāng)前正在執(zhí)行的線程休眠(暫停執(zhí)行)。static void sleep(long millis, int nanos)在指定的毫秒數(shù)加指定的納秒數(shù)內(nèi)讓當(dāng)前正在執(zhí)行的線程休眠(暫停執(zhí)行)。void start()使該線程開(kāi)始執(zhí)行;Java 虛擬機(jī)調(diào)用該線程的 run 方法。void stop()已過(guò)時(shí)。該方法具有固有的不安全性。用 Thread.stop 來(lái)終止線程將釋放它已經(jīng)鎖定的所有監(jiān)視器(作為沿堆棧向上傳播的未檢查 ThreadDeath 異常的一個(gè)自然后果)。如果以前受這些監(jiān)視器保護(hù)的任何對(duì)象都處于一種不一致的狀態(tài),則損壞的對(duì)象將對(duì)其他線程可見(jiàn),這有可能導(dǎo)致任意的行為。stop 的許多使用都應(yīng)由只修改某些變量以指示目標(biāo)線程應(yīng)該停止運(yùn)行的代碼來(lái)取代。目標(biāo)線程應(yīng)定期檢查該變量,并且如果該變量指示它要停止運(yùn)行,則從其運(yùn)行方法依次返回。如果目標(biāo)線程等待很長(zhǎng)時(shí)間(例如基于一個(gè)條件變量),則應(yīng)使用 interrupt 方法來(lái)中斷該等待。有關(guān)更多信息,請(qǐng)參閱《為何不贊成使用 Thread.stop、Thread.suspend 和 Thread.resume?》。void stop(Throwable obj)已過(guò)時(shí)。該方法具有固有的不安全性。請(qǐng)參閱 stop()以獲得詳細(xì)信息。該方法的附加危險(xiǎn)是它可用于生成目標(biāo)線程未準(zhǔn)備處理的異常(包括若沒(méi)有該方法該線程不太可能拋出的已檢查的異常)。有關(guān)更多信息,請(qǐng)參閱為何 Thread.stop、Thread.suspend 和 Thread.resume 遭到反對(duì)?。void suspend()已過(guò)時(shí)。該方法已經(jīng)遭到反對(duì),因?yàn)樗哂泄逃械乃梨i傾向。如果目標(biāo)線程掛起時(shí)在保護(hù)關(guān)鍵系統(tǒng)資源的監(jiān)視器上保持有鎖,則在目標(biāo)線程重新開(kāi)始以前任何線程都不能訪問(wèn)該資源。如果重新開(kāi)始目標(biāo)線程的線程想在調(diào)用 resume 之前鎖定該監(jiān)視器,則會(huì)發(fā)生死鎖。這類死鎖通常會(huì)證明自己是“凍結(jié)”的進(jìn)程。有關(guān)更多信息,請(qǐng)參閱為何 Thread.stop、Thread.suspend 和 Thread.resume 遭到反對(duì)?。String toString()返回該線程的字符串表示形式,包括線程名稱、優(yōu)先級(jí)和線程組。static void yield()暫停當(dāng)前正在執(zhí)行的線程對(duì)象,并執(zhí)行其他線程。
六、線程的狀態(tài)轉(zhuǎn)換圖
線程在一定條件下,狀態(tài)會(huì)發(fā)生變化。線程變化的狀態(tài)轉(zhuǎn)換圖如下:
1、新建狀態(tài)(New):新創(chuàng)建了一個(gè)線程對(duì)象。
2、就緒狀態(tài)(Runnable):線程對(duì)象創(chuàng)建后,其他線程調(diào)用了該對(duì)象的start()方法。該狀態(tài)的線程位于可運(yùn)行線程池中,變得可運(yùn)行,等待獲取CPU的使用權(quán)。
3、運(yùn)行狀態(tài)(Running):就緒狀態(tài)的線程獲取了CPU,執(zhí)行程序代碼。
4、阻塞狀態(tài)(Blocked):阻塞狀態(tài)是線程因?yàn)槟撤N原因放棄CPU使用權(quán),暫時(shí)停止運(yùn)行。直到線程進(jìn)入就緒狀態(tài),才有機(jī)會(huì)轉(zhuǎn)到運(yùn)行狀態(tài)。阻塞的情況分三種:
(一)、等待阻塞:運(yùn)行的線程執(zhí)行wait()方法,JVM會(huì)把該線程放入等待池中。
(二)、同步阻塞:運(yùn)行的線程在獲取對(duì)象的同步鎖時(shí),若該同步鎖被別的線程占用,則JVM會(huì)把該線程放入鎖池中。
(三)、其他阻塞:運(yùn)行的線程執(zhí)行sleep()或join()方法,或者發(fā)出了I/O請(qǐng)求時(shí),JVM會(huì)把該線程置為阻塞狀態(tài)。當(dāng)sleep()狀態(tài)超時(shí)、join()等待線程終止或者超時(shí)、或者I/O處理完畢時(shí),線程重新轉(zhuǎn)入就緒狀態(tài)。
5、死亡狀態(tài)(Dead):線程執(zhí)行完了或者因異常退出了run()方法,該線程結(jié)束生命周期。
七、線程的調(diào)度
1、調(diào)整線程優(yōu)先級(jí):Java線程有優(yōu)先級(jí),優(yōu)先級(jí)高的線程會(huì)獲得較多的運(yùn)行機(jī)會(huì)。
Java線程的優(yōu)先級(jí)用整數(shù)表示,取值范圍是1~10,Thread類有以下三個(gè)靜態(tài)常量: static int MAX_PRIORITY 線程可以具有的最高優(yōu)先級(jí),取值為10。static int MIN_PRIORITY 線程可以具有的最低優(yōu)先級(jí),取值為1。static int NORM_PRIORITY 分配給線程的默認(rèn)優(yōu)先級(jí),取值為5。
Thread類的setPriority()和getPriority()方法分別用來(lái)設(shè)置和獲取線程的優(yōu)先級(jí)。
每個(gè)線程都有默認(rèn)的優(yōu)先級(jí)。主線程的默認(rèn)優(yōu)先級(jí)為Thread.NORM_PRIORITY。
線程的優(yōu)先級(jí)有繼承關(guān)系,比如A線程中創(chuàng)建了B線程,那么B將和A具有相同的優(yōu)先級(jí)。JVM提供了10個(gè)線程優(yōu)先級(jí),但與常見(jiàn)的操作系統(tǒng)都不能很好的映射。如果希望程序能移植到各個(gè)操作系統(tǒng)中,應(yīng)該僅僅使用Thread類有以下三個(gè)靜態(tài)常量作為優(yōu)先級(jí),這樣能保證同樣的優(yōu)先級(jí)采用了同樣的調(diào)度方式。
2、線程睡眠:Thread.sleep(long millis)方法,使線程轉(zhuǎn)到阻塞狀態(tài)。millis參數(shù)設(shè)定睡眠的時(shí)間,以毫秒為單位。當(dāng)睡眠結(jié)束后,就轉(zhuǎn)為就緒(Runnable)狀態(tài)。sleep()平臺(tái)移植性好。
3、線程等待:Object類中的wait()方法,導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對(duì)象的 notify()方法或 notifyAll()喚醒方法。這個(gè)兩個(gè)喚醒方法也是Object類中的方法,行為等價(jià)于調(diào)用 wait(0)一樣。
4、線程讓步:Thread.yield()方法,暫停當(dāng)前正在執(zhí)行的線程對(duì)象,把執(zhí)行機(jī)會(huì)讓給相同或者更高優(yōu)先級(jí)的線程。
5、線程加入:join()方法,等待其他線程終止。在當(dāng)前線程中調(diào)用另一個(gè)線程的join()方法,則當(dāng)前線程轉(zhuǎn)入阻塞狀態(tài),直到另一個(gè)進(jìn)程運(yùn)行結(jié)束,當(dāng)前線程再由阻塞轉(zhuǎn)為就緒狀態(tài)。
6、線程喚醒:Object類中的notify()方法,喚醒在此對(duì)象監(jiān)視器上等待的單個(gè)線程。如果所有線程都在此對(duì)象上等待,則會(huì)選擇喚醒其中一個(gè)線程。選擇是任意性的,并在對(duì)實(shí)現(xiàn)做出決定時(shí)發(fā)生。線程通過(guò)調(diào)用其中一個(gè) wait 方法,在對(duì)象的監(jiān)視器上等待。直到當(dāng)前的線程放棄此對(duì)象上的鎖定,才能繼續(xù)執(zhí)行被喚醒的線程。被喚醒的線程將以常規(guī)方式與在該對(duì)象上主動(dòng)同步的其他所有線程進(jìn)行競(jìng)爭(zhēng);例如,喚醒的線程在作為鎖定此對(duì)象的下一個(gè)線程方面沒(méi)有可靠的特權(quán)或劣勢(shì)。類似的方法還有一個(gè)notifyAll(),喚醒在此對(duì)象監(jiān)視器上等待的所有線程。注意:Thread中suspend()和resume()兩個(gè)方法在JDK1.5中已經(jīng)廢除,不再介紹。因?yàn)橛兴梨i傾向。
7、常見(jiàn)線程名詞解釋
主線程:JVM調(diào)用程序mian()所產(chǎn)生的線程。
當(dāng)前線程:這個(gè)是容易混淆的概念。一般指通過(guò)Thread.currentThread()來(lái)獲取的進(jìn)程。后臺(tái)線程:指為其他線程提供服務(wù)的線程,也稱為守護(hù)線程。JVM的垃圾回收線程就是一個(gè)后臺(tái)線程。
前臺(tái)線程:是指接受后臺(tái)線程服務(wù)的線程,其實(shí)前臺(tái)后臺(tái)線程是聯(lián)系在一起,就像傀儡和幕后操縱者一樣的關(guān)系??苁乔芭_(tái)線程、幕后操縱者是后臺(tái)線程。由前臺(tái)線程創(chuàng)建的線程默認(rèn)也是前臺(tái)線程。可以通過(guò)isDaemon()和setDaemon()方法來(lái)判斷和設(shè)置一個(gè)線程是否為后臺(tái)線程。
本文出自 “熔 巖” 博客,請(qǐng)務(wù)必保留此出處http://lavasoft.blog.51cto.com/62575/27069