?? thread.txt
字號:
代碼實現(xiàn):
1、服務(wù)端:必須公開一個端口。
//產(chǎn)生服務(wù)器的實例
ServerSocket ss=new ServerSocket(4001);
//監(jiān)聽并到到一個會話
Socket socket=ss.accept();
//得到輸入的信息
socket.getInputStream();
//向外輸出信息
socket.getOutputStream();
2、客戶端:通過ip+端口連接服務(wù)端
//連接服務(wù)端
Socket socket=new Socket("主機名/ip",4001);
//得到輸入的信息
socket.getInputStream();
//向外輸出信息
socket.getOutputStream();
2、基于udp協(xié)議,
特點:不產(chǎn)生會話,可以廣播,可以批量發(fā)送。
DatagramSocket:發(fā)送接收信息,在發(fā)送時在DatagramSocket
不但要封裝字節(jié)數(shù)據(jù),還要封要封裝對應(yīng)的ip地址及
端口。
在接口時,只需封裝字節(jié)數(shù)據(jù),取值就可以了。
send(datagrampacket);
receive(datagramPacket);
DatagramPacket:承載信息
二、多線程服務(wù)框架:在服務(wù)端部署一個返轉(zhuǎn)的服務(wù),多個客戶端向其發(fā)送信息后,
其可以將該信息返轉(zhuǎn),再返回給客戶端。
1234--->4321
應(yīng)當(dāng)有幾類線程:
1、監(jiān)聽線程
2、會話線程
有一個普通類
1、服務(wù)類
系統(tǒng)先啟動的是監(jiān)聽線程,監(jiān)聽線程接收到一個請求后產(chǎn)生一個會話線程,
會話線程調(diào)用服務(wù)類做具體的處理。
連接服務(wù):
telnet 主機名 端口
五、wait、notify、notifyAll
1、三個關(guān)鍵必須在同步塊中或同步語句中執(zhí)行,否則報錯。
2、wait是使當(dāng)前線程處于等待狀態(tài)并釋放其所占用資源,其下的代碼堆棧,
當(dāng)被激活后,執(zhí)行wait語句的下一句,相當(dāng)于代碼的暫停,而不是停止。
3、notify從等待隊列中激活一個線程。
4、notifyAll激活整個等待隊列中的所有線程
七、倉庫中生產(chǎn)產(chǎn)品與消費立品的處理
Thread.currentThread:得到調(diào)用當(dāng)前方法的線程
1、一個倉庫,用隊列來實現(xiàn)
入庫:生產(chǎn)者線程生產(chǎn)產(chǎn)品放到倉庫中,具體的要求如下:
1、只有生產(chǎn)者線程才可以入庫
boolean isRunning=false;
Thread thread=Thread.currentThread();
if(thread instanceof Producer)
{
}
else
{
return;
}
isRunning=((Producer)thread).getRunning();
2、當(dāng)倉庫已滿且生產(chǎn)者線程在運行時,讓生產(chǎn)者線程等待。必須
用循環(huán),不能用if,因生產(chǎn)者被激活后可以倉庫還是滿的。
while(isRunning && store.isFull)
{
wait();
}
3、當(dāng)激活還要判斷當(dāng)生產(chǎn)者是否在運行,有可能外界已不讓其運行了。
isRunning=((Producer)thread).getRunning();
if(!isRunning)
{
return;
}
4、生產(chǎn)者生產(chǎn)一個產(chǎn)品增加倉庫中。
2、多個生品者線程
3、多個消費者線程
九、join:讓主線程等待所有的子線程執(zhí)行結(jié)束后再結(jié)束
如果不join,主線程結(jié)束了,子線程還在運行。
線程實例.join();
十二、 setPriority:(1--10),一般情況下優(yōu)先級高的先執(zhí)行。
默認(rèn)是5,最大是10
十、daemon:守護(hù)線程,JVM就是一個守護(hù)線程,守護(hù)線程主要其它線程提供服務(wù)。
在方法之前設(shè)置
為非守護(hù)線程提供服務(wù),當(dāng)所有非守護(hù)線程結(jié)束后,不管其是否運行完畢都會自動結(jié)束。
由一個守護(hù)線程產(chǎn)生的新線程也是守護(hù)線程
十一、ThreadGroup:線程組
任何一個線程都在一個線程組中,線程組下可以有子線程組及線程。
getParentGroup:得到父線程組
currentThread:得到當(dāng)前線程
getThreadGroup:得到當(dāng)前線程所在的線程組
new Thread(所屬線程組,Runnable,name)
new ThreadGroup(所屬線程組,線程組名)
遍歷線程組下的所有線程
一、取出虛擬機下的所有線程
線程組:ThreadGroup, 一個線程組可以有多個線程,也可以有很多子線程組
線程:Thread
實例化線程:
new Thread(Runnable run);
new Thread(Runnable run,String ThreadName);
new Thread(String ThreadName);
//基于runnable實現(xiàn)一個線程,ThreadName是線程的名稱,ThreadGroup代表當(dāng)前線程屬于那一個線程組
new Thread(ThreadGroup tg,Runnable run,String ThreadName);
new Thread(ThreadGroup tg,String ThreadName)
實例化線程組:
//當(dāng)前的線程組從屬于那一個線程組
new ThreadGroup(ThreadGroup tg,String ThreadName);
new ThreadGroup(String ThreadName)
方法:
currentThread():調(diào)用當(dāng)對象的線程
enumerate(Thread[] tarray): 將當(dāng)前線程的線程組及其子組中的每一個活動線程引用復(fù)制到指定的數(shù)組中。
enumerate(Thread[] tarray,false): 當(dāng)前線程組內(nèi)的每一個活動線程引用復(fù)制到數(shù)組中。
enumerate(ThreadGroup[] tarray): 將當(dāng)前線程的線程組及其子組中的每一個活動線程引用復(fù)制到指定的數(shù)組中。
enumerate(ThreadGroup[] tarray,false): 當(dāng)前線程組內(nèi)的每一個活動線程組的引用復(fù)制到數(shù)組中。 getThreadGroup();返回該線程所屬的線程組。
void interrupt(): 中斷線程。
static boolean interrupted(): 測試當(dāng)前線程是否已經(jīng)中斷。
boolean isAlive(): 測試線程是否處于活動狀態(tài)。
boolean isDaemon():測試該線程是否為守護(hù)線程。
boolean isInterrupted():測試線程是否已經(jīng)中斷。
void join():等待該線程終止。
setPriority(int newPriority) :線程的優(yōu)先級。
yield():暫停當(dāng)前正在執(zhí)行的線程對象,釋放資源,并執(zhí)行其他線程,將其放到線程隊列的最后。
activeCount() :返回當(dāng)前線程的線程組中活動線程的數(shù)目。
二、線程池:系統(tǒng)每產(chǎn)一個線程要占用較多時間,所以我們可以用線程,在池中預(yù)放n個線程,用時取出,不用時可以還回去。
三、基于線程的時間管理
四、線程實現(xiàn)死鎖
四、線程的作用
進(jìn)程內(nèi)的并發(fā)
五、線程與進(jìn)程的區(qū)別
共同點:
都是并發(fā)
不同點:
進(jìn)程有獨立的內(nèi)存空間,線程沒有獨立內(nèi)存空間。
進(jìn)程間的通信耗費較大的資源,線程間的通信比較容易。
進(jìn)程的并發(fā)是由線程實現(xiàn)的。
六、線程實現(xiàn)
1、繼承于Thread類,覆蓋run()方法,通過start啟動線程,調(diào)用run方法。
2、實現(xiàn)Runnable接口,實現(xiàn)run()方法。實例化該類,通過構(gòu)造子將其傳到一個Thread對象中
,通過start啟動線程,調(diào)用run方法
七、線程的同步
--臟讀:后一個事務(wù)用了前一個事務(wù)沒有確認(rèn)的數(shù)據(jù)
事務(wù)1
update buy set amount=amount+100 where buyID=1;
rollback;
事務(wù)2:在事務(wù)1修改但沒有執(zhí)行rollback前,執(zhí)行當(dāng)前update交提交
update buy set amount=amount+100 where buyID=1;
commit;
--覆蓋更新:后一個事務(wù)將前一個事務(wù)的更新覆蓋了。
(update一讀到就加鎖)兩個事務(wù)同時讀取,因為事務(wù)1所在主機速度快先更新并提交,
然后事務(wù)2更新并提交。
事務(wù)1
update buy set amount=amount+100 where buyID=1;
commit;
事務(wù)2:在事務(wù)1修改但沒有執(zhí)行rollback前,執(zhí)行當(dāng)前update交提交
update buy set amount=amount+100 where buyID=1;
commit;
什么是線程同步:一個對象的一個同步方法被一個線程調(diào)用,另一個線程不管調(diào)用當(dāng)前同步方法
還是其它的同步方法只能等待同步方法執(zhí)行結(jié)束,調(diào)用非同步方法不影響。
實現(xiàn)方法:
public synchronized void a1()
{
}
在線程的run方法中說明是一個同步對象,調(diào)用這個對象的所有方法都是同步方法。
synchronized(co)
{
co.test1();
}
通訊的兩種方式:
1、基于tcp/ip協(xié)議,用Sockect實現(xiàn)
特點:產(chǎn)生會話,穩(wěn)定,每一次交互都有確認(rèn)。
代碼實現(xiàn):
1、服務(wù)端:必須公開一個端口。
//產(chǎn)生服務(wù)器的實例
ServerSocket ss=new ServerSocket(4001);
//監(jiān)聽并到到一個會話
Socket socket=ss.listener();
//得到輸入的信息
socket.getInputStream();
//向外輸出信息
socket.getOutputStream();
2、客戶端:通過ip+端口連接服務(wù)端
//連接服務(wù)端
Socket socket=new Socket("主機名/ip",4001);
//得到輸入的信息
socket.getInputStream();
//向外輸出信息
socket.getOutputStream();
2、基于udp協(xié)議,
特點:不產(chǎn)生會話,可以廣播,可以批量發(fā)送。
DatagramSocket:發(fā)送接收信息
DatagramPacket:承載信息
數(shù)據(jù)庫事務(wù)中的"臟讀"."不可重復(fù)的讀"及"虛讀"
2008年02月21日 星期四 13:06
臟讀 dirty reads:當(dāng)事務(wù)讀取還未被提交的數(shù)據(jù)時,就會發(fā)生這種事件。舉例來說:Transaction 1 修改了一行數(shù)據(jù),然后 Transaction 2 在 Transaction 1 還未提交修改操作之前讀取了被修改的行。如果 Transaction 1 回滾了修改操作,那么 Transaction 2 讀取的數(shù)據(jù)就可以看作是從未存在過的。
不可重復(fù)的讀 non-repeatable reads:當(dāng)事務(wù)兩次讀取同一行數(shù)據(jù),但每次得到的數(shù)據(jù)都不一樣時,就會發(fā)生這種事件。舉例來說:Transaction 1 讀取一行數(shù)據(jù),然后 Transaction 2 修改或刪除該行并提交修改操作。當(dāng) Transaction 1 試圖重新讀取該行時,它就會得到不同的數(shù)據(jù)值(如果該行被更新)或發(fā)現(xiàn)該行不再存在(如果該行被刪除)。
虛讀 phantom read:如果符合搜索條件的一行數(shù)據(jù)在后面的讀取操作中出現(xiàn),但該行數(shù)據(jù)卻不屬于最初的數(shù)據(jù),就會發(fā)生這種事件。舉例來說:Transaction 1 讀取滿足某種搜索條件的一些行,然后 Transaction 2 插入了符合 Transaction 1 的搜索條件的一個新行。如果 Transaction 1 重新執(zhí)行產(chǎn)生原來那些行的查詢,就會得到不同的行。
事務(wù)場景是這樣的:
對于同一個銀行帳戶A內(nèi)有200元,甲進(jìn)行提款操作100元,乙進(jìn)行轉(zhuǎn)帳操作100元到B帳戶。如果事務(wù)沒有進(jìn)行隔離可能會并發(fā)如下問題:
1、第一類丟失更新:首先甲提款時帳戶內(nèi)有200元,同時乙轉(zhuǎn)帳也是200元,然后甲乙同時操作,甲操作成功取走100元,乙操作失敗回滾,帳戶內(nèi)最終為200元,這樣甲的操作被覆蓋掉了,銀行損失100元。
2、臟讀:甲取款100元未提交,乙進(jìn)行轉(zhuǎn)帳查到帳戶內(nèi)剩有100元,這是甲放棄操作回滾,乙正常操作提交,帳戶內(nèi)最終為0元,乙讀取了甲的臟數(shù)據(jù),客戶損失100元。
3、虛讀:和臟讀類似,是針對于插入操作過程中的讀取問題,如丙存款100元未提交,這時銀行做報表進(jìn)行統(tǒng)計查詢帳戶為200元,然后丙提交了,這時銀行再統(tǒng)計發(fā)現(xiàn)帳戶為300元了,無法判斷到底以哪個為準(zhǔn)?
大家好像覺得統(tǒng)計這個東西肯定是時時更新的,這種情況很正常;但是如果統(tǒng)計是在一個事務(wù)中的時候就不正常了,比如我們的一個統(tǒng)計應(yīng)用需要將統(tǒng)計結(jié)果分別輸出到電腦屏幕和遠(yuǎn)程網(wǎng)絡(luò)某臺計算機的磁盤文件中,為了
提高性能和用戶響應(yīng)我們分成2個線程,這時先完成的和后完成的統(tǒng)計數(shù)據(jù)就可能不一致,我們就不知道以哪個為準(zhǔn)了。
4、不可重復(fù)讀:甲乙同時開始都查到帳戶內(nèi)為200元,甲先開始取款100元提交,這時乙在準(zhǔn)備最后更新的時候又進(jìn)行了一次查詢,發(fā)現(xiàn)結(jié)果是100元,這時乙就會很困惑,不知道該將帳戶改為100還是0。
和臟讀的區(qū)別是,臟讀是讀取前一事務(wù)未提交的臟數(shù)據(jù),不可重復(fù)讀是重新讀取了前一事務(wù)已提交的數(shù)據(jù)。
5、第二類丟失更新:是不可重復(fù)讀的一種特例,如上,乙不做第二次查詢而是直接操作完成,帳戶內(nèi)最終為100元,甲的操作被覆蓋掉了,銀行損失100元。感覺和第一類丟失更新類似。
在多個事務(wù)并發(fā)做數(shù)據(jù)庫操作的時候,如果沒有有效的避免機制,就會出現(xiàn)種種問題。大體上有三種問題,歸結(jié)如下:
1、丟失更新
如果兩個事務(wù)都要更新數(shù)據(jù)庫一個字段X,x=100
事務(wù)A 事務(wù)B
讀取X=100
讀取X=100
寫入x=X+100
寫入x=X+200
事務(wù)結(jié)束x=200
事務(wù)結(jié)束x=300
最后x==300
這種情況事務(wù)A的更新就被覆蓋掉了、丟失了。
丟失更新說明事務(wù)進(jìn)行數(shù)據(jù)庫寫操作的時候可能會出現(xiàn)的問題。
2、不可重復(fù)讀
一個事務(wù)在自己沒有更新數(shù)據(jù)庫數(shù)據(jù)的情況,同一個查詢操作執(zhí)行兩次或多次的結(jié)果應(yīng)該是一致的;如果不一致,就說明為不可重復(fù)讀。
還是用上面的例子
事務(wù)A 事務(wù)B
讀取X=100
讀取X=100
讀取X=100
寫入x=X+100
讀取X=200
事務(wù)結(jié)束x=200
事務(wù)結(jié)束x=200
這種情況事務(wù)A多次讀取x的結(jié)果出現(xiàn)了不一致,即為不可重復(fù)讀。
再有一情況就是幻影
事務(wù)A讀的時候讀出了15條記錄,事務(wù)B在事務(wù)A執(zhí)行的過程中刪除(增加)了1條,事務(wù)A再讀的時候就變成了14(16)條,這種情況就叫做幻影讀。
不可重復(fù)讀說明了做數(shù)據(jù)庫讀操作的時候可能會出現(xiàn)的問題。
3、臟讀(未提交讀)
防止一個事務(wù)讀到另一個事務(wù)還沒有提交的記錄。
如:
事務(wù)A 事務(wù)B
讀取X=100
寫入x=X+100
讀取X=200
事務(wù)回滾x=100
讀取X=100
事務(wù)結(jié)束x=100
x鎖 排他鎖 被加鎖的對象只能被持有鎖的事務(wù)讀取和修改,其他事務(wù)無法在該對象上加其他鎖,也不能讀取和修改該對象
s鎖 共享鎖 被加鎖的對象可以被持鎖事務(wù)讀取,但是不能被修改,其他事務(wù)也可以在上面再加s鎖。
封鎖協(xié)議:
一級封鎖協(xié)議:
在事務(wù)修改數(shù)據(jù)的時候加x鎖,直到事務(wù)結(jié)束(提交或者回滾)釋放x鎖。一級封鎖協(xié)議可以有效的防止丟失更新,但是不能防止臟讀不可重復(fù)讀的出現(xiàn)。
二級封鎖協(xié)議:
在一級封鎖的基礎(chǔ)上事務(wù)讀數(shù)據(jù)的時候加s鎖,讀取之后釋放。二級封鎖協(xié)議可以防止丟失更新,臟讀。不能防止不可重復(fù)讀。
三級封鎖協(xié)議:
在一級封鎖的基礎(chǔ)上事務(wù)讀數(shù)據(jù)的時候加s鎖,直到事務(wù)結(jié)束釋放。二級封鎖協(xié)議可以防止丟失更新,臟讀,不可重復(fù)讀
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -