一笑旺、上節(jié)課回顧
????1题禀、多線程的創(chuàng)建和啟動
????????方法一:通過繼承Thread類
????????????classMyThreadextendsThread{
? ????????????????? @Override
? ????????????????? publicvoidrun(){
? ? ? ????????????????????? //此處的代碼,并發(fā)的執(zhí)行穴店。撕捍。
????????????????? ? }
????????????????}
????????????publicstaticvoidmain(String[]args){
? ????????????????? MyThreadt1=newMyThread();//創(chuàng)建線程對象
? ????????????????? t1.start();//啟動線程——>準備就緒,就等著被CPU調(diào)度執(zhí)行
????????}
????????方法二:通過實現(xiàn)Runnable接口
????????????????classMyThread2implementsRunnable{
????????????????????????private....//成員變量
????????????????????????????publicvoidrun(){
?????????????????? }
????????????????}
????????????publicstaticvoidmain(String[]args){
????????????????????MyThread2mt=newMyThread2();
????????????????????Threadt2=newThread(mt);
????????????????????Threadt3=newThread(mt);
????????????????????t2.start();
????????????????????t3.start();
????????}
????區(qū)別:
????????1泣洞、一種通過繼承的方式忧风,不能再有其他的父類。而通過實現(xiàn)接口球凰,可以再繼承其他的父類狮腿。
????????2腿宰、通過Runnable接口的方式,可以很方便的實現(xiàn)多個線程之間的數(shù)據(jù)共享缘厢。
????2吃度、線程的常用方法:
????????A:線程的Id,線程的唯一標識:long的整數(shù)贴硫,終身不變椿每。
? ????????????? 由系統(tǒng)自動編號,程序員只能獲取getId()英遭,不能更改
????????B:線程的Name:線程的名稱
? ????????????? 設置和獲取
????????????? ? setName()
????????????? ? getName()
????????????? ? 構造方法:提供名稱
? ? ????????? ? Thread類構造方法:Thread(String name);
????????C:獲取當前的線程對象:靜態(tài)的方法
? ????????????? Thread.currentThread()--->Thread對象
? ? ? ? ? ? ? ? 誰正在被執(zhí)行间护,就獲取哪個線程對象——>獲取當前的對象
? ? ? ? ? ? ? ? 理解為:該方法在哪個線程中調(diào)用,就是獲取哪個線程對象挖诸。
????????D:線程的Priority汁尺,優(yōu)先級
????????? ? int整數(shù):
? ? ? ????????????? MAX_PRIORITY:10
? ? ????????????? ? MIN_PRIORITY:1
? ? ? ????????????? NORM_PRIORITY:5
? ? ? ????????? t1,t2,t3..main...-->默認的優(yōu)先級:
????????? ????? setPriority(),getPriority()
????????????? ? 優(yōu)先級高,執(zhí)行的機會多多律。優(yōu)先級低均函,執(zhí)行的機會少。
????????E:線程的睡眠:sleep菱涤,靜態(tài)的方法
? ????????????????? Thread.sleep(time)
? ????????????????? 當前正在執(zhí)行的線程苞也,進入了睡眠,放棄了CPU的執(zhí)行粘秆。和哪個線程對象來調(diào)用無關如迟。
? ? ? ????? 理解為:該方法寫在哪個線程中調(diào)用,就是哪個線程進入睡眠攻走。
????????F:線程的合并:join
????????????????? ? t1殷勘,t2,main線程
? ? ? ????????????? main線程中:執(zhí)行了t1.join()
? ????????????? 等待線程死亡——>在main線程中昔搂,要等待t1線程結束后玲销,main線程才能執(zhí)行。
????????G:守護線程:daemon
? ????????????????? setDaemon(true)-->設置為守護線程摘符,為前臺線程提供服務贤斜,如果所有的前臺線程都結束了,那么守護線程就結束了逛裤。
? ????????????????????? isDaemon()-->boolean
3瘩绒、線程的生命周期
????????線程的生命周期:線程這"一輩子"
????????從創(chuàng)建一個線程對象開始,直到該線程結束带族,死亡锁荔。一個線程只有一輩子,只能被啟動一次蝙砌。
?
????????新建:線程對象創(chuàng)建出來了
? ????????????? Thread t1 = new Thread();//"剛出生"
????????就緒:執(zhí)行start()方法阳堕,萬事準備完畢
? ? ????????????隨時可以被CPU調(diào)度執(zhí)行
????????運行:自動執(zhí)行run()方法
? ??????死亡:線程結束了
????????阻塞:
????????? ????? 暫時不能執(zhí)行:
? ????? 等待:
? ? ? ????????? 有期限:sleep(time)
? ? ? ????????? 無期限:join()
4跋理、多線程之間的共享數(shù)據(jù)安全問題(臨界資源問題)
????????多個線程訪問共享的數(shù)據(jù),可能存在數(shù)據(jù)的不安全恬总。
????????t1線程訪問數(shù)據(jù):中途被其他線程搶跑了薪介,它還修改了。越驻。。t1再搶回來道偷,數(shù)據(jù)已經(jīng)被改了缀旁,就是不安全。
5勺鸦、如何解決臨界資源的問題
????????同步:原子性操作:(化學中表示最小顆粒并巍,不可再分)
????????????計算機中用于表示一次性執(zhí)行完畢。
????????同步:一次性執(zhí)行完畢换途。
????????語法:關鍵字synchronized
????????????用法一:同步代碼塊:一次只能被一個線程執(zhí)行懊渡,中間不允許其他線程插入執(zhí)行的。
????????????????//t1,t2,t3,t4
????????????????synchronized(鎖對象){//開始給對象上鎖,t1
????????????????}//打開對象的鎖
????特征:
????????A:synchronized小括號里的對象军拟,是鎖對象剃执,并要求多線程的情況下,鎖對象必須是同一個對象懈息。
????????B:synchronized大括號里的代碼肾档,就是同步執(zhí)行的代碼”杓蹋或者說是加了鎖的代碼怒见。意味著每次只能被一個線程執(zhí)行。
????????C:同步的代碼越少越好姑宽,在保證安全的情況下遣耍,提高性能。
????????D:鎖對象:理論上誰都可以炮车,只要是多個線程訪問的共同對象即可舵变。
? ????????????? this關鍵字,外面創(chuàng)建對象傳入瘦穆,類名.class棋傍,"abc",
????用法二:同步方法:一個方法就是同步难审,只能被一個線程來執(zhí)行瘫拣,中間不允許其他線程來打斷執(zhí)行
????????????publicsynchronizedvoidtest(){
????}
????????StringBuffer,StringBuilder,
????同步的原理:對象的"互斥鎖"
????????鎖:打開的狀態(tài)
????????鎖:關閉的狀態(tài)
Java中的任意對象告喊,身上都有互斥鎖麸拄。默認就是打開狀態(tài)
多線程同步上鎖鎖不着擅痢?
????多線程存在共享的數(shù)據(jù)安全
????鎖對象拢切,是否是多個線程能夠訪問的共同的對象蒂萎。99%
????Class類的對象:類編譯后的字節(jié)碼文件對應的對象。
????Object類:
????????對象.getClass()-->Class
????Person:
????????????1.對象.getClass()-->Class
????????????????????p1.getClass()-->Class ---->Person.class
????????? ? 2.類名.class-->Class
????????????????????Person.class
? ? ????????3.Class類中有一個靜態(tài)的方法:forName("類名")
????????????????????Class.forName("com.qf.demo01.Person");-->Class
同步的優(yōu)缺點:
????好處:解決了數(shù)據(jù)安全的問題
????缺點:降低了效率淮椰,可能會死鎖
2.1五慈、同步方法
????????同步代碼塊:使用synchronized關鍵字包裹了一塊代碼,讓這塊代碼同步執(zhí)行主穗。就是每次只能一個線程來執(zhí)行泻拦。
????????同步方法:使用synchronized關鍵字修飾一個方法,這個方法同步執(zhí)行忽媒。就是每次只能一個線程來執(zhí)行争拐。
????????普通的方法:對象調(diào)用。鎖定的對象晦雨,就是this對象架曹。
????????靜態(tài)的方法:類調(diào)用。鎖定的對象闹瞧,就是類名.class
????????同步的原理:利用對象的互斥鎖绑雄。
????????????????每個線程來訪問,只能有一個線程進入執(zhí)行奥邮,第一個動作鎖對象(上鎖)绳慎。來保證其他線程不能進入執(zhí)行。等到該線程結束這個同步代碼塊或者同步方法漠烧,釋放鎖對象(開鎖)杏愤,才允許其他的線程來訪問。
????線程安全的類:
????????????StringBuffer
????????????Vector
????????????HashTable
????????????Collections已脓,集合的工具類
2.2珊楼、線程之間的通信
????????線程之間的通信:wait(),notify()度液,notifyAll()
????????????wait()——>讓線程進入阻塞狀態(tài)厕宗,暫停執(zhí)行。一直阻塞
????????????notify()——>喚醒線程堕担,wait()住的線程已慢,被喚醒。如果多個線程wait()了霹购,喚醒其中的一個佑惠。
????????????notifyAll()——>喚醒所有。
? ??語法要求:必須在同步中,由同步的鎖對象來調(diào)用膜楷。否則java.lang.IllegalMonitorStateException異常旭咽。
生產(chǎn)者消費者模型:
????????生產(chǎn)者(線程t1)負責生產(chǎn)產(chǎn)品,存入容器中(固定容量)赌厅,消費者(線程t2)從容器中獲取產(chǎn)品消費掉穷绵。
????容器:
? ????? 生產(chǎn)者:持有資源,生產(chǎn)產(chǎn)品特愿,存入容器中
? ????? 消費者:持有資源仲墨,消費掉產(chǎn)品。
?
????容器滿了:最多裝8個雞蛋
? ????? 生產(chǎn)者:持有資源揍障,暫停執(zhí)行——直到容器還能繼續(xù)裝目养。
? ? ?????? 鎖對象.wait()——>會讓線程進入阻塞狀態(tài)。暫停執(zhí)行亚兄。notify(),notifyAll()
????? ? 消費者:持有資源采驻,直接消費审胚。。
????容器空了:最少0個礼旅。
? ????? 生產(chǎn)者:持有資源膳叨,生產(chǎn),存入痘系。菲嘴。
????? ? 消費者:持有資源,暫停執(zhí)行——直到容器中有產(chǎn)品
? ? ? ? 鎖對象.wait()——>會讓線程進入阻塞狀態(tài)汰翠。暫停執(zhí)行龄坪。notify(),notifyAll()
????代碼分析:
????????1复唤、產(chǎn)品類:Egg()-->id
????????2健田、產(chǎn)生者:線程
????????? ????? cpu執(zhí)行,run()-->生產(chǎn)雞蛋佛纫,裝入容器
????????3妓局、消費者:線程
????????????? ? cpu執(zhí)行,run()-->從容器中獲取雞蛋呈宇,吃掉(打印好爬。。)
????容器對象:
????????????Class實現(xiàn)容器
????????????數(shù)組: Egg[] arr = new Egg[8];
????????????集合:棧甥啄,后進先出
? ??????????集合:隊列存炮,先進先出
????同步的代碼:
????????鎖的是容器對象:
wait()和sleep()方法的區(qū)別:
????????出處不同:
????????????????sleep()方法是Thread類中定義的。
????????????????wait()方法是Object類中定義的。
????????解除阻塞的方式不同
????????????????sleep()是時間到僵蛛,自己醒尚蝌。
????????????????wait()方法等待被喚醒:notify(),或者是notifyAll()
????????對鎖資源的釋放情況
????????????????sleep()充尉,不釋放飘言,抱著不撒手
????????????????wait(),釋放
三驼侠、總結
????同步方法姿鸿,同步代碼塊
????????????????synchronized(鎖對象){
????????}
????????????????publicsynchronizedvoidtest(){? ? ?
????????}
注意點:
? ? 同步代碼塊:自己指定鎖對象。
? ? 同步方法:鎖對象是固定的倒源。
? ? ? ? 普通的同步方法:鎖對象:this
? ? ? ? 靜態(tài)的同步方法:鎖對象:類名.class
線程之間的通信:生產(chǎn)者消費者模型