兩種實(shí)現(xiàn)多線程的區(qū)別
1.繼承thread類的,是由子類重寫run,調(diào)用start,他是直接找到子類的run方法。
2.實(shí)現(xiàn)runnable接口,是創(chuàng)建thread類時(shí)傳入runnable的引用。thread記住這個(gè)成員。調(diào)用時(shí)判斷runnable引用是否為空,調(diào)用runnable的run方法。
3.繼承thread的問題是,如果已經(jīng)有父類了,那么就不能使用了
4.即使自己定義的類有了父類,但是我們可以實(shí)現(xiàn)接口。這樣完成多線程定義。
匿名多線程的實(shí)現(xiàn)
// 匿名類實(shí)現(xiàn)多線程
//1.集成thread匿名類
new Thread("芙蓉姐姐"){
@Override
public void run() {
for (int i = 0; i < 100; i++) {
//Thread.currentThread() 獲取當(dāng)前線程對(duì)象 getname()獲取到線程的名字
System.out.println(Thread.currentThread().getName()+"=>"+i);
}
}
}.start(); //啟動(dòng)線程
//2.實(shí)現(xiàn)runnable接口匿名類
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
//Thread.currentThread() 獲取當(dāng)前線程對(duì)象 getname()獲取到線程的名字
System.out.println(Thread.currentThread().getName()+"=>"+i);
}
}
},"鳳姐").start();
獲取多線程名稱方法 Thread.currentThread() 獲取當(dāng)前線程對(duì)象 getname()獲取到線程的名字
線程休眠 使用sleep(毫秒)當(dāng)前線程休眠后會(huì)讓出CPU時(shí)間片給其他線程使用,經(jīng)過毫秒后會(huì)再次執(zhí)行
守護(hù)線程 使用setDeamon() 設(shè)置一個(gè)線程為守護(hù)線程,該線程不會(huì)單獨(dú)執(zhí)行,當(dāng)其他非守護(hù)線程執(zhí)行結(jié)束時(shí)自動(dòng)退出。守護(hù)線程本質(zhì)上和普通線程沒什么區(qū)別,唯一的區(qū)別就是在虛擬機(jī)的離開,如果User Thread(用戶線程)全部撤離,則守護(hù)線程就沒有服務(wù)對(duì)象了也就撤離。典型的就是java垃圾回收線程
Join() 插入到線程,令當(dāng)前線程暫停,等待指定的線程執(zhí)行結(jié)束后,當(dāng)前線程在繼續(xù)
線程優(yōu)先級(jí)。 設(shè)置優(yōu)先級(jí)使用的 setPriority 盡可能先執(zhí)行優(yōu)先級(jí)高的線程,但不保證一定先執(zhí)行
(資源互斥)線程的同步問題,當(dāng)多個(gè)線程訪問公共資源(臨界資源)時(shí)為了保證線程安全性。也就是同一時(shí)刻只袁旭一個(gè)線程訪問公共資源,我們使用同步代碼塊,來(lái)達(dá)到鎖定資源的目標(biāo)
synchronized (obj) { //多線程訪問時(shí),鎖定共享資源,一個(gè)線程訪問是,其他要等待期結(jié)束后 ,才能進(jìn)入同步快
}
也可采用鎖對(duì)象,來(lái)做同步
private Lock lock = new ReentrantLock();
lock.lock();//在進(jìn)入鎖
lock.unlock();
(線程協(xié)同工作)同步問題:有時(shí)我們線程間的執(zhí)行有順序要求。如何讓指定線程工作或等待。
線程死鎖。多線程同步時(shí),如果多代碼嵌套,使用了相同的鎖,就可能出現(xiàn)死鎖。
線程的聲明周期
創(chuàng)建 new
就緒 start
運(yùn)行 run
阻塞 sleep
死亡 程序運(yùn)行結(jié)束