最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

帶你快速搞定java并發(fā)庫

 更新時間:2021年07月15日 10:11:06   作者:香菜聊游戲  
本文主要介紹了java高并發(fā)寫入用戶信息到數(shù)據(jù)庫的幾種方法,具有很好的參考價值。下面跟著小編一起來看下吧,希望能給你帶來幫助

一、總覽

計(jì)算機(jī)程序 = 數(shù)據(jù) + 算法。

并發(fā)編程的一切根本原因是為了保證數(shù)據(jù)的正確性,線程的效率性。

Java并發(fā)庫共分為四個大的部分,如下圖

Executor 和 future 是為了保證線程的效率性

Lock 和數(shù)據(jù)結(jié)構(gòu) 是為了維持?jǐn)?shù)據(jù)的一致性。

Java并發(fā)編程的時候,思考順序?yàn)椋?/p>

對自己的數(shù)據(jù)要么加鎖。要么使用提供的數(shù)據(jù)結(jié)構(gòu),保證數(shù)據(jù)的安全性

調(diào)度線程的時候使用Executor更好的調(diào)度。

二、Executor總覽

Executor 提供一種將任務(wù)提交與每個任務(wù)將如何運(yùn)行的機(jī)制(包括線程使用的細(xì)節(jié)、調(diào)度等)分離開來的方法。

相當(dāng)于manager,老板讓manager去執(zhí)行一件任務(wù),具體的是誰執(zhí)行,什么時候執(zhí)行,就不管了。

看上圖的繼承關(guān)系,介紹幾個

內(nèi)置的線程池基本上都在這里

newScheduledThreadPool 定時執(zhí)行的線程池

newCachedThreadPool 緩存使用過的線程

newFixedThreadPool 固定數(shù)量的線程池

newWorkStealingPool 將大任務(wù)分解為小任務(wù)的線程池

三、繼承結(jié)構(gòu)

構(gòu)造函數(shù)

包含一個定時的service

public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
    return new DelegatedScheduledExecutorService
        (new ScheduledThreadPoolExecutor(1));
}
static class DelegatedScheduledExecutorService
        extends DelegatedExecutorService
        implements ScheduledExecutorService {
    private final ScheduledExecutorService e;
    DelegatedScheduledExecutorService(ScheduledExecutorService executor) {
        super(executor);
        e = executor;
    }

四、怎么保證只有一個線程

定時執(zhí)行的時候調(diào)用這個方法,調(diào)用過程如下,注意看其中的注釋,由上往下的調(diào)用順序

public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
                                                 long initialDelay,
                                                 long delay,
                                                 TimeUnit unit) {
    if (command == null || unit == null)
        throw new NullPointerException();
    if (delay <= 0)
        throw new IllegalArgumentException();
    ScheduledFutureTask<Void> sft =
        new ScheduledFutureTask<Void>(command,
                                      null,
                                      triggerTime(initialDelay, unit),
                                      unit.toNanos(-delay));
    RunnableScheduledFuture<Void> t = decorateTask(command, sft);
    sft.outerTask = t;
    //  延遲執(zhí)行
    delayedExecute(t);
    return t;
}
private void delayedExecute(RunnableScheduledFuture<?> task) {
    if (isShutdown())
        reject(task);
    else {
        // 加入任務(wù)隊(duì)列
        super.getQueue().add(task);
        if (isShutdown() &&
            !canRunInCurrentRunState(task.isPeriodic()) &&
            remove(task))
            task.cancel(false);
        else
            // 確保執(zhí)行
            ensurePrestart();
    }
}
// 如果worker數(shù)量小于corePoolSize,創(chuàng)建新的線程,其他情況不處理
void ensurePrestart() {
    int wc = workerCountOf(ctl.get());
    if (wc < corePoolSize)
        addWorker(null, true);
    else if (wc == 0)
        addWorker(null, false);
}

五、怎么保證時間可以定時執(zhí)行

public ScheduledFuture<?> schedule(Runnable command,
                                   long delay,
                                   TimeUnit unit) {
    if (command == null || unit == null)
        throw new NullPointerException();
    RunnableScheduledFuture<?> t = decorateTask(command,
        new ScheduledFutureTask<Void>(command, null,
                                      triggerTime(delay, unit)));
    delayedExecute(t);
    return t;
}

在每次執(zhí)行的時候會把下一次執(zhí)行的時間放進(jìn)任務(wù)中

private long triggerTime(long delay, TimeUnit unit) {
    return triggerTime(unit.toNanos((delay < 0) ? 0 : delay));
}
/**
 * Returns the trigger time of a delayed action.
 */
long triggerTime(long delay) {
    return now() +
        ((delay < (Long.MAX_VALUE >> 1)) ? delay : overflowFree(delay));
}

FutureTask 定時是通過LockSupport.parkNanos(this, nanos);LockSupport.park(this);

private int awaitDone(boolean timed, long nanos)
    throws InterruptedException {
    final long deadline = timed ? System.nanoTime() + nanos : 0L;
    WaitNode q = null;
    boolean queued = false;
    for (;;) {
        if (Thread.interrupted()) {
            removeWaiter(q);
            throw new InterruptedException();
        }
        int s = state;
        if (s > COMPLETING) {
            if (q != null)
                q.thread = null;
            return s;
        }
        else if (s == COMPLETING) // cannot time out yet
            Thread.yield();
        else if (q == null)
            q = new WaitNode();
        else if (!queued)
            queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
                                                 q.next = waiters, q);
        else if (timed) {
            nanos = deadline - System.nanoTime();
            if (nanos <= 0L) {
                removeWaiter(q);
                return state;
            }
            //注意這里
            LockSupport.parkNanos(this, nanos);
        }
        else //注意這里
            LockSupport.park(this);
    }
}

總結(jié):Executor是通過將任務(wù)放在隊(duì)列中,生成的futureTask。然后將生成的任務(wù)在隊(duì)列中排序,將時間最近的需要出發(fā)的任務(wù)做檢查。如果時間不到,就阻塞線程到下次出發(fā)時間。

注意:newSingleThreadScheduledExecutor只會有一個線程,不管你提交多少任務(wù),這些任務(wù)會順序執(zhí)行,如果發(fā)生異常會取消下面的任務(wù),線程池也不會關(guān)閉,注意捕捉異常

六、使用

ScheduledExecutorService single = Executors.newSingleThreadScheduledExecutor();
Runnable runnable1 = () -> {
    try {
        Thread.sleep(4000);
        System.out.println("11111111111111");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
};
Runnable runnable2 = () -> {
    try {
        Thread.sleep(4000);
        System.out.println("222");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
};
single.scheduleWithFixedDelay(runnable1,0,1, TimeUnit.SECONDS);
single.scheduleWithFixedDelay(runnable2,0,2, TimeUnit.SECONDS);

11111111111111 222 11111111111111 222 11111111111111

在項(xiàng)目中要注意關(guān)閉線程池

actionService = Executors.newSingleThreadScheduledExecutor();
        actionService.scheduleWithFixedDelay(() -> {
            try {
                Thread.currentThread().setName("robotActionService");
                Integer robotId = robotQueue.poll();
                if (robotId == null) {
                    //    關(guān)閉線程池
                    actionService.shutdown();
                } else {
                    int aiLv = robots.get(robotId);
                    if (actionQueueMap.containsKey(aiLv)) {
                        ActionQueue actionQueue = actionQueueMap.get(aiLv);
                        actionQueue.doAction(robotId);
                    }
                }
            } catch (Exception e) {
                //    捕捉異常
                LOG.error("",e);
            }
        }, 1, 1, TimeUnit.SECONDS);

總結(jié)

本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • java Unicode和UTF-8之間轉(zhuǎn)換實(shí)例

    java Unicode和UTF-8之間轉(zhuǎn)換實(shí)例

    這篇文章主要介紹了java Unicode和UTF-8之間轉(zhuǎn)換實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Java有序鏈表的合并實(shí)現(xiàn)方法

    Java有序鏈表的合并實(shí)現(xiàn)方法

    這篇文章主要通過兩個例題為大家介紹一下Java合并兩個及以上有序鏈表的實(shí)現(xiàn)方法,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價值,需要的可以參考一下
    2023-04-04
  • IDEA自動清理類中未使用的import包的操作方法

    IDEA自動清理類中未使用的import包的操作方法

    在項(xiàng)目開發(fā)中,經(jīng)常會引入很多未使用的import包,這不僅增加了編譯時間,還會使代碼可讀性變差,設(shè)置IDEA自動清理未使用的import包,可以提高代碼的可讀性,本文給大家介紹IDEA自動清理類中未使用的import包的方法,感興趣的朋友一起看看吧
    2024-09-09
  • java使用minio上傳下載文件完整版教程

    java使用minio上傳下載文件完整版教程

    本示例教程介紹了如何使用SpringBoot框架結(jié)合MinIO服務(wù)實(shí)現(xiàn)文件的上傳和下載功能,并將文件信息存儲在數(shù)據(jù)庫的file表中,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-09-09
  • Java并發(fā)編程深入理解之Synchronized的使用及底層原理詳解 上

    Java并發(fā)編程深入理解之Synchronized的使用及底層原理詳解 上

    在并發(fā)編程中存在線程安全問題,主要原因有:1.存在共享數(shù)據(jù) 2.多線程共同操作共享數(shù)據(jù)。關(guān)鍵字synchronized可以保證在同一時刻,只有一個線程可以執(zhí)行某個方法或某個代碼塊,同時synchronized可以保證一個線程的變化可見(可見性),即可以代替volatile
    2021-09-09
  • idea中MavenWeb項(xiàng)目不能創(chuàng)建Servlet的解決方案

    idea中MavenWeb項(xiàng)目不能創(chuàng)建Servlet的解決方案

    這篇文章主要介紹了idea中MavenWeb項(xiàng)目不能創(chuàng)建Servlet的解決方案,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-02-02
  • java公眾平臺通用接口工具類HttpConnectUtil實(shí)例代碼

    java公眾平臺通用接口工具類HttpConnectUtil實(shí)例代碼

    下面小編就為大家分享一篇java公眾平臺通用接口工具類HttpConnectUtil實(shí)例代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • springboot+mybatis攔截器方法實(shí)現(xiàn)水平分表操作

    springboot+mybatis攔截器方法實(shí)現(xiàn)水平分表操作

    這篇文章主要介紹了springboot+mybatis攔截器方法實(shí)現(xiàn)水平分表操作,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下
    2022-08-08
  • JAVA發(fā)送HTTP請求的多種方式詳細(xì)總結(jié)

    JAVA發(fā)送HTTP請求的多種方式詳細(xì)總結(jié)

    目前做項(xiàng)目中有一個需求是這樣的,需要通過Java發(fā)送url請求,查看該url是否有效,這時我們可以通過獲取狀態(tài)碼來判斷,下面這篇文章主要給大家介紹了關(guān)于JAVA發(fā)送HTTP請求的多種方式總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • JavaSwing FlowLayout 流式布局的實(shí)現(xiàn)

    JavaSwing FlowLayout 流式布局的實(shí)現(xiàn)

    這篇文章主要介紹了JavaSwing FlowLayout 流式布局的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12

最新評論

同心县| 特克斯县| 呼和浩特市| 衡山县| 肃宁县| 河北省| 微博| 年辖:市辖区| 新安县| 三都| 信宜市| 鹤庆县| 克什克腾旗| 沙田区| 界首市| 弥渡县| 兴和县| 淮北市| 武汉市| 治多县| 哈巴河县| 高邑县| 徐汇区| 克拉玛依市| 砚山县| 乌鲁木齐县| 津南区| 吉林省| 布尔津县| 盐池县| 镇赉县| 阜城县| 株洲市| 明光市| 阳春市| 正定县| 晋江市| 托里县| 禹城市| 福贡县| 东港市|