java.util.concurrent簡介

java.util.concurrent簡介

java.util.concurrent包提供了很多有用的類蓖扑,方便我們進(jìn)行并發(fā)程序的開發(fā)淋袖。本文將會做一個總體的簡單介紹悼凑。

主要的組件

java.util.concurrent包含了很多內(nèi)容罚屋, 本文將會挑選其中常用的一些類來進(jìn)行大概的說明:

  • Executor
  • ExecutorService
  • ScheduledExecutorService
  • Future
  • CountDownLatch
  • CyclicBarrier
  • Semaphore
  • ThreadFactory

Executor

Executor是一個接口晦炊,它定義了一個execute方法鞠鲜,這個方法接收一個Runnable宁脊,并在其中調(diào)用Runnable的run方法。

我們看一個Executor的實現(xiàn):

public class Invoker implements Executor {
    @Override
    public void execute(Runnable r) {
        r.run();
    }
}

現(xiàn)在我們可以直接調(diào)用該類中的方法:

    public void execute() {
        Executor executor = new Invoker();
        executor.execute( () -> {
            log.info("{}", Thread.currentThread().toString());
        });
    }

注意镊尺,Executor并不一定要求執(zhí)行的任務(wù)是異步的朦佩。

ExecutorService

如果我們真正的需要使用多線程的話并思,那么就需要用到ExecutorService了庐氮。

ExecutorService管理了一個內(nèi)存的隊列,并定時提交可用的線程宋彼。

我們首先定義一個Runnable類:

public class Task implements Runnable {
    @Override
    public void run() {
        // task details
    }
}

我們可以通過Executors來方便的創(chuàng)建ExecutorService:

ExecutorService executor = Executors.newFixedThreadPool(10);

上面創(chuàng)建了一個ThreadPool弄砍, 我們也可以創(chuàng)建單線程的ExecutorService:

ExecutorService executor =Executors.newSingleThreadExecutor();

我們這樣提交task:

public void execute() { 
    executor.submit(new Task()); 
}

因為ExecutorService維持了一個隊列,所以它不會自動關(guān)閉输涕, 我們需要調(diào)用executor.shutdown() 或者executor.shutdownNow()來關(guān)閉它音婶。

如果想要判斷ExecutorService中的線程在收到shutdown請求后是否全部執(zhí)行完畢,可以調(diào)用如下的方法:

try {
            executor.awaitTermination( 5l, TimeUnit.SECONDS );
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

ScheduledExecutorService

ScheduledExecutorService和ExecutorService很類似莱坎,但是它可以周期性的執(zhí)行任務(wù)衣式。

我們這樣創(chuàng)建ScheduledExecutorService:

ScheduledExecutorService executorService
                = Executors.newSingleThreadScheduledExecutor();

executorService的schedule方法,可以傳入Runnable也可以傳入Callable:

Future<String> future = executorService.schedule(() -> {
        // ...
        return "Hello world";
    }, 1, TimeUnit.SECONDS);

    ScheduledFuture<?> scheduledFuture = executorService.schedule(() -> {
        // ...
    }, 1, TimeUnit.SECONDS);

還有兩個比較相近的方法:

scheduleAtFixedRate( Runnable command, long initialDelay, long period, TimeUnit unit )

scheduleWithFixedDelay( Runnable command, long initialDelay, long delay, TimeUnit unit ) 

兩者的區(qū)別是前者的period是以任務(wù)開始時間來計算的檐什,后者是以任務(wù)結(jié)束時間來計算碴卧。

Future

Future用來獲取異步執(zhí)行的結(jié)果∧苏可以調(diào)用cancel(boolean mayInterruptIfRunning) 方法來取消線程的執(zhí)行住册。

我們看下怎么得到一個Future對象:

public void invoke() {
    ExecutorService executorService = Executors.newFixedThreadPool(10);

    Future<String> future = executorService.submit(() -> {
        // ...
        Thread.sleep(10000l);
        return "Hello world";
    });
}

我們看下怎么獲取Future的結(jié)果:

if (future.isDone() && !future.isCancelled()) {
    try {
        str = future.get();
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }
}

future還可以接受一個時間參數(shù),超過指定的時間瓮具,將會報TimeoutException荧飞。

try {
    future.get(10, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
    e.printStackTrace();
}

CountDownLatch

CountDownLatch是一個并發(fā)中很有用的類,CountDownLatch會初始化一個counter名党,通過這個counter變量叹阔,來控制資源的訪問。我們會在后面的文章詳細(xì)介紹传睹。

CyclicBarrier

CyclicBarrier和CountDownLatch很類似耳幢。CyclicBarrier主要用于多個線程互相等待的情況,可以通過調(diào)用await() 方法等待蒋歌,知道達(dá)到要等的數(shù)量帅掘。

public class Task implements Runnable {

    private CyclicBarrier barrier;

    public Task(CyclicBarrier barrier) {
        this.barrier = barrier;
    }

    @Override
    public void run() {
        try {
            LOG.info(Thread.currentThread().getName() + 
              " is waiting");
            barrier.await();
            LOG.info(Thread.currentThread().getName() + 
              " is released");
        } catch (InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }
    }

}

public void start() {

    CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () -> {
        // ...
        LOG.info("All previous tasks are completed");
    });

    Thread t1 = new Thread(new Task(cyclicBarrier), "T1"); 
    Thread t2 = new Thread(new Task(cyclicBarrier), "T2"); 
    Thread t3 = new Thread(new Task(cyclicBarrier), "T3"); 

    if (!cyclicBarrier.isBroken()) { 
        t1.start(); 
        t2.start(); 
        t3.start(); 
    }
}

Semaphore

Semaphore包含了一定數(shù)量的許可證,通過獲取許可證堂油,從而獲得對資源的訪問權(quán)限修档。通過 tryAcquire()來獲取許可,如果獲取成功府框,許可證的數(shù)量將會減少吱窝。

一旦線程release()許可,許可的數(shù)量將會增加。

我們看下怎么使用:

static Semaphore semaphore = new Semaphore(10);

public void execute() throws InterruptedException {

    LOG.info("Available permit : " + semaphore.availablePermits());
    LOG.info("Number of threads waiting to acquire: " + 
      semaphore.getQueueLength());

    if (semaphore.tryAcquire()) {
        try {
            // ...
        }
        finally {
            semaphore.release();
        }
    }

}

ThreadFactory

ThreadFactory可以很方便的用來創(chuàng)建線程:

public class ThreadFactoryUsage implements ThreadFactory {
    private int threadId;
    private String name;

    public ThreadFactoryUsage(String name) {
        threadId = 1;
        this.name = name;
    }

    @Override
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r, name + "-Thread_" + threadId);
        log.info("created new thread with id : " + threadId +
                " and name : " + t.getName());
        threadId++;
        return t;
    }
}

愿與諸君共進(jìn)步院峡,大量的面試題及答案還有資深架構(gòu)師錄制的視頻錄像:有Spring兴使,MyBatis,Netty源碼分析照激,高并發(fā)发魄、高性能、分布式俩垃、微服務(wù)架構(gòu)的原理励幼,JVM性能優(yōu)化、分布式架構(gòu)等這些成為架構(gòu)師必備的知識體系口柳,可以微信搜索539413949獲取苹粟,最后祝大家都能拿到自己心儀的offer

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市跃闹,隨后出現(xiàn)的幾起案子嵌削,更是在濱河造成了極大的恐慌,老刑警劉巖望艺,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件苛秕,死亡現(xiàn)場離奇詭異,居然都是意外死亡荣茫,警方通過查閱死者的電腦和手機(jī)想帅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來啡莉,“玉大人港准,你說我怎么就攤上這事∵中溃” “怎么了浅缸?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長魄咕。 經(jīng)常有香客問我衩椒,道長,這世上最難降的妖魔是什么哮兰? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任毛萌,我火速辦了婚禮,結(jié)果婚禮上喝滞,老公的妹妹穿的比我還像新娘阁将。我一直安慰自己,他們只是感情好右遭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布做盅。 她就那樣靜靜地躺著缤削,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吹榴。 梳的紋絲不亂的頭發(fā)上亭敢,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天,我揣著相機(jī)與錄音图筹,去河邊找鬼帅刀。 笑死,一個胖子當(dāng)著我的面吹牛婿斥,可吹牛的內(nèi)容都是我干的劝篷。 我是一名探鬼主播哨鸭,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼民宿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了像鸡?” 一聲冷哼從身側(cè)響起活鹰,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎只估,沒想到半個月后志群,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蛔钙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年锌云,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吁脱。...
    茶點(diǎn)故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡桑涎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出兼贡,到底是詐尸還是另有隱情攻冷,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布遍希,位于F島的核電站等曼,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏凿蒜。R本人自食惡果不足惜禁谦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望废封。 院中可真熱鬧州泊,春花似錦、人聲如沸虱饿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至渴肉,卻和暖如春冗懦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背仇祭。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工披蕉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人乌奇。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓没讲,卻偏偏與公主長得像,于是被迫代替她去往敵國和親礁苗。 傳聞我的和親對象是個殘疾皇子爬凑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內(nèi)容