第4章 Java并發(fā)編程的基礎(chǔ)

線程的優(yōu)先級:

線程的優(yōu)先級越高,占用CPU的能力越強;

線程中斷:

調(diào)用線程對象的interrupt()函數(shù)后,線程并不會立即中斷,而是將線程的中斷標識設(shè)為true,只有遇到阻塞函數(shù)(sleep()、wait()、join())時,才停止阻塞,拋出異常,并將中斷標識重置為false;
如何正確中斷線程:
1.使用阻塞函數(shù)捕獲中斷,在異常處理中跳出任務(wù),使線程結(jié)束運行;

class Runner implements Runnable{
    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(2);
            } catch (InterruptedException e) {
                return;
            }
        }
    }
}

2.使用isInterrupted()判斷線程是否處于中斷狀態(tài),若是中斷狀態(tài)則跳出任務(wù),使線程結(jié)束運行;

class Runner implements Runnable{
    @Override
    public void run() {
        while (true){
           if (Thread.currentThread().isInterrupted()){
               return;
           }
        }
    }
}

3.使用中斷標識;

class Runner implements Runnable{
    public volatile boolean on = true;
    @Override
    public void run() {
        while (true){
           if (on == false){
               return;
           }
        }
    }
}
線程獲取鎖狀態(tài)變化:
線程獲取鎖狀態(tài)變化

1.運行中的線程嘗試獲取鎖,若獲取成功則繼續(xù)運行,獲取失敗則進入同步隊列;
2.notify()將等待隊列的首節(jié)點加入同步隊列,notifyAll()將等待隊列的所有節(jié)點加入同步隊列;
3.同步隊列的首節(jié)點獲取同步狀態(tài)成功,即對應線程獲取鎖成功;
4.同步隊列首節(jié)點的后續(xù)節(jié)點繼續(xù)通過自旋來獲取同步狀態(tài);

線程間通信:

多個線程相互配合完成計算任務(wù);
通信方式:
1.使用volatile變量作為信號量;
2.使用synchronized進行鎖同步;
3.使用wait()和notify()進行通信;

//線程1
synchronized(lock){
    while(條件不滿足 ){
        lock.wait();
    }
    doSomething();
}
//線程2等待超時
synchronized(lock){
    while(條件不滿足 || remainTime > 0){
        lock.wait(remain)
        remainTime = futureTime - notTime;
    }
}
//線程3
synchronized(lock){
    改變條件;
    lock.notify();
}

使用wait()和notify()時線程的狀態(tài)變化


線程的狀態(tài)變化

a.RUNNING狀態(tài)的線程獲取鎖失敗則進入BOLOCKED狀態(tài);
b.RUNNING狀態(tài)的線程調(diào)用wait()方法后進入WAITING狀態(tài);
c.WAITING狀態(tài)的線程被別的線程notify()后進入BLOCKED狀態(tài);
d.BLOCKED狀態(tài)的線程獲取鎖成功后進入RUNNING狀態(tài);
4.使用并發(fā)計數(shù)器CountDownLatch阻塞線程;

public class CountDownLatchTest {
    //計數(shù)器初始值為2
    static CountDownLatch countDownLatch = new CountDownLatch(2);

    public static void main(String[] args){
        Thread thread1 = new Thread(new Runner(), "thread 1");
        Thread thread2 = new Thread(new Runner(), "thread 2");
        try {
            thread1.start();
            thread2.start();
            //main線程阻塞,直到計數(shù)器值為0時被喚醒
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("main thread");
        return;
    }

    static class Runner implements Runnable{
        @Override
        public void run() {
            try {
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName());
                //計數(shù)器減一
                countDownLatch.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}
數(shù)據(jù)庫連接池示例:

數(shù)據(jù)庫連接池

1.初始化一定數(shù)量的連接對象放入隊列中;
2.多個線程并發(fā)的取出、歸還conn對象;
3.通過加鎖來解決并發(fā)問題;

線程池示例:
線程池

1.多個worker線程并發(fā)從job隊列中獲取job;
2.job隊列為空時worker線程進入waiting狀態(tài),往job隊列中添加job時notify()等待的線程,取出job并執(zhí)行;
3.worker線程從非空的job隊列中取出job,然后執(zhí)行job;
缺點:不能指定job到指定的worker線程執(zhí)行;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容