




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
Java多線程和并發(fā)第十四章本章目標什么是多線程中斷線程線程狀態(tài)線程屬性同步死鎖什么是多線程我們來看下熟悉的windows操作系統(tǒng),它是多任務的:在同一時刻有多個程序在同時運行。多線程就是引入了多任務的思想:單個程序看起來可以同時處理多個“任務”,這個任務被稱之為線程。Let’sGo,看一個多線程的程序感受下。什么是多線程示例publicstaticvoidmain(String[]args){//Model1:定義二個線程,并調(diào)用它們Threadt1=newThread(newThreadTest1("線程一"));Threadt2=newThread(newThreadTest1("線程二"));t1.start();t2.start();//Model2:沒有使用線程調(diào)用情況//ThreadTest1t1=newThreadTest1("線程一");//ThreadTest1t2=newThreadTest1("線程二");//t1.run();//t2.run();//分別執(zhí)行Model和Model2,看看輸出結果,第一個多線程輸出,第二個單線程輸出}publicclassThreadTest1implementsRunnable{privateStringthreadName;//線程名稱publicThreadTest1(StringthreadName){this.threadName=threadName;}publicvoidrun(){try{inti=0;//一個死循環(huán)輸出計數(shù),每次加1while(true){Thread.sleep(1000);//每個1秒鐘輸出一次System.out.print("當前線程名稱:"
+threadName); System.out.print(“計數(shù):"
+(++i));} if(i==10)break;//退出循環(huán)}catch(Exceptione){}}}如何創(chuàng)建線程繼承Thread類或者實現(xiàn)Runnable接口重寫run方法調(diào)用start()方法啟動線程線程中斷在JDK1.0時代,有個stop()方法可以終止線程,目前已經(jīng)被廢棄了。現(xiàn)在沒有強制終止線程的方法了,但是可以使用interrupt來請求中斷線程如何使用呢?我們在剛剛的例子里修改下一般來講,中斷線程操作通常放在異常處理中去做if(!Thread.currentThread().isInterrupted()&&i==10&&threadName.equals("線程一")){Thread.currentThread().interrupt();}線程方法小結Thread已經(jīng)學習的方法start():啟動線程run():必須重載這個方法,里面放線程處理代碼interrupt():發(fā)送中斷請求,如果當前線程sleep了,則拋出InterruptException異常isInterrupt():檢查線程是否已經(jīng)被中斷了currentThread():返回代表當前執(zhí)行的線程線程狀態(tài)New(新生)使用了new操作符創(chuàng)建一個線程之后Runnable(可運行)調(diào)用了start方法之后Blocked(被阻塞)調(diào)用了sleep方法線程調(diào)用一個在I/O上被阻塞的操作有人調(diào)用了suspend方法Dead(死亡)run方法正常退出死亡發(fā)生異常終止了run方法而使線程死亡線程調(diào)度圖線程調(diào)度示例圖線程方法小結Thread增加一些方法isAlive():線程已經(jīng)啟動且沒有終止,則返回truestop():停止線程,已過時suspend():掛起當前線程執(zhí)行過程,已過時resume():恢復線程,在suspend之后用,已過時join():等待直到指定的線程死亡join(longmillis):等待直到指定的線程死亡或經(jīng)過指定毫秒數(shù)線程屬性在這里我們將要討論的內(nèi)容線程優(yōu)先級守護線程線程組線程優(yōu)先級在Java中,每個線程都有優(yōu)先級可以使用setPriority方法進行設置MIN_PRIORITY(在Thread中定義為1)MAX_PRIORITY(在Thread中定義為10)NORM_PRIORITY(在Thread中定義為5)示例演示守護線程什么是守護線程?守護線程的唯一作用就是為其他線程提供服務。例如計時器線程就是一個例子當只剩下守護線程時,就沒有運行程序的必要了通過setDaemon(booleanisDaemon)設定該方法必須在線程開始執(zhí)行之前調(diào)用線程組按照功能對線程進行分類,類別即為線程組根據(jù)ThreadGroup類創(chuàng)建要查明某個線程組中是否有線程處于可運行狀態(tài)要中斷線程組中所有線程StringgroupName=“瀏覽器線程組”;ThreadGroupg=newThreadGroup(groupName);//創(chuàng)建線程組Threadt=newThread(g,threadName);//創(chuàng)建線程If(g.activeCount==0){//allthreadsinthegroupghavestopped}errupt();//中斷線程組中所有線程線程小結如何創(chuàng)建線程繼承Tread類或?qū)崿F(xiàn)Runnable接口,重寫run()方法線程狀態(tài)新生,可運行,被阻塞,死亡線程優(yōu)先級守護線程線程組線程示例演示同步在實際應用中,通常會遇到多個線程對相同資源進行共享訪問。比如2個線程,它們都對同一對象進行訪問,根據(jù)它們訪問銀行賬號的不同順序,就有可能產(chǎn)生腐蝕的對象,這就叫做競爭條件示例演示同步假設我們有個Bank類,它有個方法,模擬將一定數(shù)額的錢從一個賬戶轉(zhuǎn)移到另一個賬戶中publicvoidtransfer(intfrom,intto,doubleamount){
if(accounts[from]<amount)return;//金額不夠不允許轉(zhuǎn)出System.out.print("執(zhí)行線程:"+Thread.currentThread().getName());
accounts[from]-=amount;System.out.print("從"+from+"轉(zhuǎn)出到"+to+"中,轉(zhuǎn)出金額為"+amount);
accounts[to]+=amount;System.out.println("銀行總金額為:"+getTotalBalance());}publicvoidrun(){while(true){inttoAccount=(int)(bank.size()*Math.random());doubleamount=maxAmount*Math.random();bank.transfer(fromAccount,toAccount,amount);}}同步結果發(fā)現(xiàn),開始總金額還是一致的,后來銀行總金額變了。這就叫做腐蝕對象問題出在哪里了呢?假如兩個線程同時執(zhí)行accounts[to]+=amount我們分解這段代碼將accounts[to]載入寄存器增加amount將結果寫回accounts[to]假設線程1執(zhí)行了第一步,第二步后中斷了,此時線程2更新了accounts數(shù)組中同一項,接著線程1被喚醒并完成了第三步。這時,線程2所做的更新被抹去了。同步怎么解決這個比較嚴重的問題呢?ReentrantLock類:JDK1.5之后才出現(xiàn)的synchronized關鍵字//在Bank類中新增一個如下屬性privateLockbankLock=newReentrantLock();//修改transfer方法publicvoidtransfer(intfrom,intto,doubleamount){
bankLock.lock();try{//剛剛transfer的方法內(nèi)容}finally{
bankLock.unlock();}}條件對象當一個線程進入臨界區(qū),發(fā)現(xiàn)它必須滿足某個條件后才能執(zhí)行,這就需要你使用條件對象來管理在我們剛剛transfer方法中有一行如下代碼其實我們不能這么寫,應該讓線程進入等待狀態(tài),當滿足條件的時候再繼續(xù)運行if(accounts[from]<amount)return;//金額不夠不允許轉(zhuǎn)出bankLock.lock();try{while(accounts[from]<amount){//wait}//執(zhí)行}finally{
bankLock.unlock();}條件對象//在Bank類中新增一個如下屬性privateConditioncondition;//在構造函數(shù)中初始化它Condition=bankLock.newCondition();//修改transfer方法publicvoidtransfer(intfrom,intto,doubleamount){bankLock.lock();try{
while(accounts[from]<amount){ condition.await();}…condition.signalAll();}finally{bankLock.unlock();}}Synchronized關鍵字在方法返回值之前加上synchronized條件對象,利用Object類中wait()和notifyAll()publicsynchronizedvoidtransfer(intfrom,intto,doubleamount){…}Publicsynchronizedvoidtransfer(intfrom,intto,doubleamount){while(accounts[from]<amount){ wait();}…notifyAll();}同步快舉例說明:如果該方法被調(diào)用,它會獲取所關聯(lián)類對象的鎖,也就是說它被調(diào)用時,Bank.class對象的鎖會被鎖住Publicvoidtransfer(intfrom,intto,doubleamount){
synchronized(this){
accounts[from]-=amount;accounts[to]+=amount;}}修改后的線程調(diào)度圖死鎖鎖和條件不能解決多線程中的所有問題。比如下列情況:賬戶1:¥200;賬戶2:¥300;線程1:把¥300從賬戶1轉(zhuǎn)到賬戶2;線程2:把¥400從賬戶2轉(zhuǎn)到賬戶1;2個線程都會被阻塞,誰都無法執(zhí)行,因為2個賬戶中余額都不足。這就叫做死鎖修改我們同步的例子,在main方法中修改,就會死鎖TransferRunnabler=newTransferRunnable(b,i,10000);死鎖很遺憾,在Java中沒有任何東西能夠避免或打破這種死鎖現(xiàn)象。你必須仔細的設計你的程序以確保死鎖不會發(fā)生。同步小結什么叫腐蝕對象如何解決腐蝕對象,利用同步synchronized關鍵字ReentrantLock類條件對象Object類中wait()和notify()方法Condition類中await()和signalAll()方法死鎖作業(yè)作業(yè)1:有5個哲學家,他們的生活方式是交替地進行思考和進餐。哲學家們共用一張圓桌,分
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 材料科學應用考核試卷
- 出口合同標準文本 電匯
- 個人應聘合同標準文本
- 公家鋪面轉(zhuǎn)讓合同標準文本
- 共同裝修協(xié)議合同標準文本
- 人事助理聘用合同范例
- 倉庫訂單合同范例
- 中介購房服務合同標準文本
- 住宅商業(yè)施工合同標準文本
- 2025年華電煤業(yè)集團有限公司校園招聘筆試參考題庫附帶答案詳解
- 駕照體檢表完整版本
- 大數(shù)據(jù)管理與應用概論 課件 3.5 大數(shù)據(jù)時代的管理決策變革
- 母嬰護理員(月嫂)培訓完整課件
- 婦幼保健院關于創(chuàng)建三級婦幼保健院調(diào)整四大部業(yè)務科室設置的通知
- 防詐騙銀行知識講座
- 物業(yè)員工消防知識培訓
- 醫(yī)用氣體配送服務投標方案(技術標)
- 20100927-宣化上人《愣嚴咒句偈疏解》(簡體全)
- 中考物理復習-等效電路“節(jié)點分析”解析
- 原發(fā)性骨質(zhì)疏松癥診療指南(2022)解讀
- 圖書館學概論復習
評論
0/150
提交評論