A
進(jìn)程
操作系統(tǒng)中運(yùn)行的一個(gè)任務(wù)(一個(gè)應(yīng)用程序就運(yùn)行在一個(gè)進(jìn)程中)婉商。
進(jìn)程是包含了某些資源的內(nèi)存區(qū)域;操作系統(tǒng)利用進(jìn)程把它的工作劃分為一些功能單元淳衙。
線程
進(jìn)程中包含的一個(gè)或者多個(gè)執(zhí)行單元稱為線程(thread);線程只歸屬于一個(gè)進(jìn)程并且它只能訪問該進(jìn)程所擁有的資
源缀雳。當(dāng)操作系統(tǒng)創(chuàng)建一個(gè)進(jìn)程后绝葡,該進(jìn)程會(huì)自動(dòng)申請(qǐng)一個(gè)名為主線程或者首要線程的線程。
一個(gè)線程是一個(gè)進(jìn)程的順序執(zhí)行流竞膳,同類的多個(gè)線程共享一塊空間一組系統(tǒng)資源,線程本身有一個(gè)供程序執(zhí)行的堆
棧锉走,線程在切換時(shí)負(fù)荷小藕届,因此線程也被稱為輕復(fù)合進(jìn)程休偶,一個(gè)進(jìn)程中有多個(gè)線程。
線程和進(jìn)程的區(qū)別
一個(gè)進(jìn)程至少要有一個(gè)線程。
進(jìn)程在執(zhí)行過程中擁有獨(dú)立的內(nèi)存資源昔驱,而多個(gè)線程共享內(nèi)存上忍。
線程不能獨(dú)立的執(zhí)行窍蓝,必須依存于應(yīng)用程序中它抱,由應(yīng)用程序提供多個(gè)線程執(zhí)行控制观蓄。
線程使用的場(chǎng)合
線程通常用于子啊一個(gè)程序中需要同時(shí)完成多個(gè)任務(wù)的情況侮穿。我們可以將每一個(gè)任務(wù)定義為一個(gè)線程亲茅。使他們得以一同工作。
創(chuàng)建線程的方法
Thread類是線程類袭祟,我們可以聽取通過繼承類并重寫run方法來定義一個(gè)具體的線程鸟召;啟動(dòng)線程時(shí)調(diào)用start()方
法;此時(shí)就會(huì)納入到線程調(diào)用等待獲取時(shí)間片來開始執(zhí)行run方法中的闊以邏輯。
并發(fā)原理
多個(gè)線程“同時(shí)”工作指示我們感官上的一種表現(xiàn)。事實(shí)上是線程并發(fā)運(yùn)行的碌廓;OS將時(shí)間劃分為很多的時(shí)間片段(時(shí)間
片),盡可能的均勻給每一個(gè)線程慨蛙,獲取時(shí)間片的線程被CPU運(yùn)行期贫,而其他線程處于等待异袄。所以微觀上是走走停
停烤蜕,宏觀上是都在運(yùn)行讽营;這種現(xiàn)象叫做并發(fā),但不是絕對(duì)意義上的同時(shí)發(fā)生膜蠢。
使用Runnable創(chuàng)建并啟動(dòng)線程
實(shí)現(xiàn)Runnable接口并重寫run方法來定義線程體挑围,然后再創(chuàng)建線程的時(shí)候?qū)unnble的實(shí)例傳入并啟動(dòng)線程贪惹。
實(shí)現(xiàn)Runnable接口創(chuàng)建線程這樣的好處在于可以將線程與線程要執(zhí)行的任務(wù)分開減少耦合寂嘉;同時(shí)java是單繼承的,定
義一個(gè)類實(shí)現(xiàn)Runnable接口這樣的做法可以更好的去實(shí)現(xiàn)其他父類或者接口硼端,因?yàn)榻涌谑嵌鄬?shí)現(xiàn)(多繼承)的關(guān)
系珍昨。
線程常用API
//獲取線程ID
long id=th.getId();
System.out.println(id);
//獲取線程名稱
String name=th.getName();
System.out.println(name);
th.setPriority(2);//設(shè)置線程優(yōu)先級(jí)
int a=th.getPriority();//獲取線程優(yōu)先級(jí)镣典,默認(rèn)為5
System.out.println(a);
線程優(yōu)先級(jí)
線程的切換是線程調(diào)度控制的兄春,我們無法通過代碼來干涉,但我們可以通過提高線程的優(yōu)先級(jí)來最大程度的改善
線程獲取時(shí)間片的幾率哑姚。
線程的優(yōu)先級(jí)被劃分為10級(jí)叙量,值分別是1-10九串,其中1最低,10最高猪钮。線程提供3個(gè)常量來表示最低躬贡、最高以及默認(rèn)
優(yōu)先級(jí):
---Thread.MIN_PRIORITY,
---Thread.MAX_PRIORITY,
---Thread.NORM_PRIORITY,
Thread.sleep();靜態(tài)方法拂玻,該方法會(huì)使當(dāng)前線程進(jìn)入阻塞狀態(tài)指定毫秒檐蚜,當(dāng)阻塞指定毫秒后沿侈,當(dāng)前線程就會(huì)進(jìn)入到
Runnable狀態(tài)缀拭,等待分配時(shí)間片蛛淋。
static void yield():該方法用于使用當(dāng)前線程主動(dòng)讓出CPU時(shí)間片回到Runnable狀態(tài)褐荷,等待分配時(shí)間片。
void join():該方法用于等待當(dāng)前線程結(jié)束。該方法聲明InterruptException层宫。
守護(hù)線程
與普通線程在表現(xiàn)上沒有區(qū)別;唯一不同點(diǎn):當(dāng)進(jìn)程中只剩下守護(hù)線程時(shí)杨伙,所有的守護(hù)線程都
會(huì)強(qiáng)制終止。
---守護(hù)線程的床創(chuàng)建:void setDeamon(boolean b)萌腿;GC就是運(yùn)行在一個(gè)守護(hù)線程上限匣。
線程同步
多個(gè)線程并發(fā)讀寫同一個(gè)臨界資源時(shí)會(huì)發(fā)生“線程并發(fā)安全問題”。
常見的臨界資源:
--多線程共享實(shí)例變量哮奇;
--多線程共享靜態(tài)公共變量膛腐。
若想解決線程安全問題,需要將異步操作變成同步操作鼎俘。
--異步操作:多線程并發(fā)的操作哲身,相當(dāng)于各干各的。
--同步操作:有先后順序的操作贸伐,相當(dāng)于你干完后我在再干勘天。
synchronized關(guān)鍵字是java中的同步鎖
通信
Socket:通常稱為套接字伏伐,用于描述IP和端口材蹬,是一個(gè)通信鏈的句柄;在Internet上的主機(jī)
一般運(yùn)行了多個(gè)服務(wù)軟件,同時(shí)提供幾種服務(wù)辉川。每種服務(wù)都打開一個(gè)socket,并綁定在一
個(gè)端口上欲诺,不同的端口對(duì)應(yīng)不同的服務(wù)。
應(yīng)用程序通常通過“套接字”向網(wǎng)絡(luò)發(fā)出請(qǐng)求或者應(yīng)答網(wǎng)絡(luò)請(qǐng)求。Socket和ServerSocket位于
java.net包中。ServerSocket用于服務(wù)器伴网,Socket是建立網(wǎng)絡(luò)連接是使用的动分,在連接成功
時(shí)應(yīng)用程序兩端都會(huì)有一個(gè)Socket實(shí)例。操作這個(gè)實(shí)例就會(huì)完成所需的會(huì)話。
獲取本地地址和端口號(hào)
--int getLocalPort()右核;獲取本地的端口號(hào)
--InetAddress getLocalAddress():用于獲取Socket綁定的本地地址菱鸥。
--使用InetAddress獲取本地地址的方法:String getCanonicalHostName()染苛;
--String getHostAddress():返回IP地址字符串(以文本形式表現(xiàn))
獲取遠(yuǎn)端地址和端口號(hào)
--int getPort();獲取遠(yuǎn)端使用的端口號(hào)
--InetAddress getInetAddress();獲取套接字(Socket)綁定的遠(yuǎn)端地址
獲取網(wǎng)絡(luò)輸入流和網(wǎng)絡(luò)輸出流
--通過Socket獲取網(wǎng)絡(luò)輸入和輸出流的方法如下:
InputStream getInputStream():返回此套接字的輸入流;
OutputStream getOutputStream():用于獲取此套接字的輸出流。