更新時(shí)間:2022-05-31 09:40:13 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽1568次
java多線程編程環(huán)境下并發(fā)是常見(jiàn)問(wèn)題,這兩天看了鎖相關(guān)的問(wèn)題,記錄下兩個(gè)簡(jiǎn)單的用鎖實(shí)現(xiàn)等待/喚醒機(jī)制的demo。
public class WaitAndNotify {
private static boolean flag = true;
private static Object lock = new Object();
public static void main(String[] args) {
Thread waitThread = new Thread(new Wait(), "WaitThread");
waitThread.start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread notifyThread = new Thread(new Notify(), "NotifyThread");
notifyThread.start();
}
private static class Wait implements Runnable {
@Override
public void run() {
synchronized (lock) {
while (flag) {
System.out.println(Thread.currentThread() + " flag是true,wait。。" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread() + " flag是false,開(kāi)始繼續(xù)工作" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
}
}
}
private static class Notify implements Runnable {
@Override
public void run() {
synchronized (lock){
System.out.println(Thread.currentThread() + " 持有鎖,發(fā)出通知" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
lock.notifyAll();
flag = false;
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
打印結(jié)果:
Thread[WaitThread,5,main] flag是true,wait。。18:55:28
Thread[NotifyThread,5,main] 持有鎖,發(fā)出通知18:55:29
Thread[WaitThread,5,main] flag是false,開(kāi)始繼續(xù)工作18:55:34
分析:根據(jù)程序可以看到,大致的過(guò)程就是:WaitThread拿到lock對(duì)象的鎖,然后根據(jù)flag標(biāo)記,自己調(diào)用了wait()方法,從而釋放鎖并進(jìn)入WAITTING狀態(tài)。NotifyThread此時(shí)獲取了lock對(duì)象的鎖,然后進(jìn)行notify操作,此時(shí)WaitThread被喚醒,但是,它不能立刻執(zhí)行,因?yàn)閱拘丫€程N(yùn)otifyThread還持有“該對(duì)象的同步鎖”。必須等到NotifyThread線程釋放了“對(duì)象的同步鎖”之后,也就是同步代碼塊執(zhí)行完以后,即睡眠5秒以后,等待線程WaitThread才能獲取到“對(duì)象的同步鎖”進(jìn)而繼續(xù)運(yùn)行。
public class ReenterLockCondition {
private static ReentrantLock lock = new ReentrantLock();
private static Condition condition = lock.newCondition();
private static Runnable runnable = () -> {
try {
lock.lock();
System.out.println(Thread.currentThread().getName() + "進(jìn)入等待。。");
condition.await();
System.out.println(Thread.currentThread().getName() + "繼續(xù)執(zhí)行");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
};
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(runnable, "thread--1");
thread.start();
Thread.sleep(2000);
lock.lock();
condition.signal();
System.out.println("主線程發(fā)出信號(hào)");
lock.unlock();
}
}
打印結(jié)果:
thread--1進(jìn)入等待。。
主線程發(fā)出信號(hào)
thread--1繼續(xù)執(zhí)行
分析:這里thread–1線程是等待線程,主線程就是喚醒想成。開(kāi)始thread-1啟動(dòng),拿到鎖,然后進(jìn)入等待并且釋放鎖,2秒后,主線程拿到鎖,然后發(fā)出信號(hào)并釋放鎖,最后,thread–1繼續(xù)執(zhí)行。
以上就是關(guān)于“實(shí)現(xiàn)Java鎖的兩種機(jī)制”的介紹,大家如果想了解更多相關(guān)知識(shí),不妨來(lái)關(guān)注一下動(dòng)力節(jié)點(diǎn)的Java視頻教程,里面的課程內(nèi)容由淺到深,通俗易懂,即使沒(méi)有基礎(chǔ)也可以聽(tīng)懂,希望對(duì)大家的學(xué)習(xí)能夠有所幫助。
相關(guān)閱讀
Java實(shí)驗(yàn)班
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
Java就業(yè)班
有基礎(chǔ) 直達(dá)就業(yè)
Java夜校直播班
業(yè)余時(shí)間 高薪轉(zhuǎn)行
Java在職加薪班
工作1~3年,加薪神器
Java架構(gòu)師班
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)