成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

模擬可取消任務(wù)的股票交易處理程序(百萬訂單)(FutureTask類)

TigerChain / 1681人閱讀

摘要:并且線程可被中斷,那么在訂單處理過程中接收的取消請求會結(jié)束剩余的處理流程。演示可取消任務(wù)的股票交易處理程序交易訂單創(chuàng)建數(shù)量為的線程池來執(zhí)行訂單。邪惡線程邪惡線程,隨機的取消某些訂單。判斷是否取消成功,在每兩個請求之間讓邪惡線程睡一會。

FutureTask類

重點是那個股票交易處理程序的例子,認(rèn)真看三遍。本文花了三個小時。

GitHub代碼歡迎star。

小白認(rèn)為學(xué)習(xí)語言最好的方式就是模仿思考別人為什么這么寫。

FutureTask類同時實現(xiàn)類Runnable接口和Future接口。因此,F(xiàn)utureTask類技能擁有Runnable接口提供的異步計算能力,也能擁有Future接口提供的返回值給調(diào)用方的Future對象取消任務(wù)的能力。FutureTask類可以用于封裝Callable和Runnable接口。

//Future future = executor.submit(Callable);
FutureTask future = new FutureTaks(Callable);
future.run()

run方法會調(diào)用任務(wù),并將任務(wù)的計算結(jié)果賦值給Future對象。

也可以將FutureTask實例交給Executor對象用于執(zhí)行。

executor.submit(future);

由于FutureTask類也實現(xiàn)了Future接口,因此FutureTak接口實例可以用來取消任務(wù),檢查任務(wù)等。

創(chuàng)建可取消的任務(wù)。

取消任務(wù)可以使用執(zhí)行器返回的Future對象,而創(chuàng)建和執(zhí)行任務(wù)可以使用前面討論的FutureTask類。

開發(fā)可以處理上百萬次請求的模擬器。會發(fā)送數(shù)千條數(shù)據(jù)交易請求給模擬器。模擬器包含的線程池用于處理這些請求。
還將編寫一個“邪惡”的線程,它會隨機選擇諾干訂單,并且嘗試取消他們。如果訂單已經(jīng)執(zhí)行,取消請求會失敗。
如果在訂單在被分配給線程執(zhí)行之前接收到取消請求,那么訂單會被取消。如果交易訂單正在執(zhí)行。并且線程可被中斷,
那么在訂單處理過程中接收的取消請求會結(jié)束剩余的處理流程。從而取消訂單。

/**
 * Created by guo on 2018/2/15.
 * 演示可取消任務(wù)的股票交易處理程序
 */
public class StocksOrderProcessor {
    static final int MAX_NUMBER_OF_ORDER = 1_000_000;       //交易訂單
    //1、創(chuàng)建數(shù)量為1000的線程池來執(zhí)行訂單。經(jīng)過測試1000個線程,CPU維持在70%-80%左右。
    static private ExecutorService executor = Executors.newFixedThreadPool(1000);
    //2、創(chuàng)建ArrayList來保存執(zhí)行執(zhí)行訂單的引用
    static private List ordersToProcess = new ArrayList<>();

    /**
     * 創(chuàng)建內(nèi)部私有類OrderExecutor以處理訂單執(zhí)行的業(yè)務(wù)邏輯。
     * OrderExecutor實現(xiàn)了Callable接口以支持異步調(diào)用。
     */
    public static class OrderExecutor implements Callable {
        int id = 0;
        int count = 0;
         //3、傳入整型變量id來記錄訂單編號。
        public OrderExecutor(int id) {
            this.id = id;
        }

        @Override
        public Object call() throws Exception {
            try {
                //4、將技術(shù)設(shè)為1000,每次計數(shù)前,讓線程休眠一段不同的時間
                while (count < 1000) {
                    count++;
                    //5、通過讓線程休眠一段不同的時間,模擬現(xiàn)實中每個訂單需要不同的處理時間。
                    Thread.sleep(new Random(
                            System.currentTimeMillis() % 10).nextInt(10));
                }
                System.out.println("Successfully executed order:" + id);
            } catch (Exception ex) {
                throw (ex);
            }
            return id;
        }
    }
}
主函數(shù)
public static void main(String[] args) {

    System.out.printf("Submitting %d trades%n", MAX_NUMBER_OF_ORDER);
    //6、通過循環(huán)遍歷,提交一百萬訂單。
    for (int i = 0; i < MAX_NUMBER_OF_ORDER; i++) {
        submitOrder(i);
    }
    //7、創(chuàng)建“邪惡”線程嘗試隨機的取消某些訂單。
    //每當(dāng)執(zhí)行到這里時,就會創(chuàng)建一些取消請求,并針對待處理的訂單列表中存儲的Future對象執(zhí)行。
    new Thread(new EvilThread(ordersToProcess)).start();


    System.out.println("Cancelling a few order at random");
    try {

        //8a、某些訂單可能已經(jīng)被處理,模擬器就會繼續(xù)處理剩余訂單。
        // b、如果訂單在執(zhí)行器分配線程之前被取消,就將永遠(yuǎn)不會執(zhí)行。
        // c、為了留有足夠的時間結(jié)束所有待處理的訂單,讓執(zhí)行器等待30秒。
        executor.awaitTermination(30, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }


    System.out.println("Checking status before shutdown");
    int count = 0;
    //9a、通過循環(huán)遍歷,統(tǒng)計有多少訂單被成功取消。
    // b、對于訂單中每一個Future對象,調(diào)用isCancelld方法。
    // c、如果對應(yīng)的被成功取消,則方法返回true
    for (Future f : ordersToProcess) {
        if (f.isCancelled()) {
            count++;
        }
    }
    System.out.printf("%d trades cancelled%n", count);
    //10、立即停止執(zhí)行器釋放分配的所有資源 (貌似我的百萬訂單根本停不下來啊,求解?。?    executor.shutdownNow();

}

private static void submitOrder(int id) {
    //6、a 創(chuàng)建一個Callable實例,每個實例都有為一個的Id供跟蹤
    Callable callable = new OrderExecutor(id);
    //6、b 調(diào)用ExecutorService的submit方法可將創(chuàng)建的任務(wù)提交以待執(zhí)行。
    //并且將submit方法返回的對象放到待處理訂單的數(shù)組里列表中。
    ordersToProcess.add(executor.submit(callable));
}
邪惡線程
/**
 * 邪惡線程,隨機的取消某些訂單。
 */
class EvilThread implements Runnable {
    private List ordersToProcess;
     //1、在構(gòu)造函數(shù)中傳入待處理的訂單列表,這樣可以對某一些Future對象發(fā)送取消請求。
    public EvilThread(List future) {
        this.ordersToProcess = future;
    }

    @Override
    public void run() {
         //2、創(chuàng)建100個取消請求
        Random myNextKill = new Random(System.currentTimeMillis() % 100);
        for (int i = 0; i < 100; i++) {
            //3、隨機選擇Future對象進行取消。
            int index = myNextKill.nextInt(StocksOrderProcessor.MAX_NUMBER_OF_ORDER);
            //4、調(diào)用Future對象的cancel方法以發(fā)送請求,并將cancel方法的參數(shù)設(shè)為ture。表示任務(wù)可能會在執(zhí)行過程中被中斷。
            boolean cancel = ordersToProcess.get(index).cancel(true);
            //5、判斷是否取消成功,
            if (cancel) {
                System.out.println("Cancel Order Succeded:" + index);
            } else {
                System.out.println("cancel Order Failed:" + index);
            }
            try {
                //6、在每兩個請求之間讓“邪惡”線程睡一會。
                Thread.sleep(myNextKill.nextInt(100));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

程序運行后部分輸出如下:

Submitting 1000000 trades

Successfully executed order:28
Successfully executed order:380
Successfully executed order:288
Successfully executed order:120
Cancelling a few order at random
Successfully executed order:116
Successfully executed order:1004
Successfully executed order:1005

Cancel Order Succeded:698021
cancel Order Failed:98832(重點)
...
Successfully executed order:12268
Successfully executed order:12420
Successfully executed order:13190
Successfully executed order:12199

Checking status before shutdown
99 trades cancelled(重點)
Successfully executed order:14045      //估計Kill線程太多了,遺漏這個了.求解.

從輸出可以看到:

訂單698021被成功取消,這個訂單還未執(zhí)行,

訂單98832的取消請求失敗了,因為這個訂單已經(jīng)執(zhí)行結(jié)束.

在發(fā)送的100個請請求中,有99個被成功取下.也可能是100%,取決你的電腦配置.

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/68496.html

相關(guān)文章

  • Java多線程進階(四二)—— J.U.C之executors框架:Future模式

    摘要:本文首發(fā)于一世流云的專欄一模式簡介模式是多線程設(shè)計模式中的一種常見模式,它的主要作用就是異步地執(zhí)行任務(wù),并在需要的時候獲取結(jié)果。二中的模式在多線程基礎(chǔ)之模式中,我們曾經(jīng)給出過模式的通用類關(guān)系圖。 showImg(https://segmentfault.com/img/bVbiwcx?w=1000&h=667); 本文首發(fā)于一世流云的專欄:https://segmentfault.co...

    marek 評論0 收藏0
  • 基于LinkedBlockingQueue實現(xiàn)股票交易系統(tǒng)

    摘要:與基于數(shù)組的隊列相同,重載的構(gòu)造函數(shù)可以接受集合指定的初始值。這種隊列比基于數(shù)組阻塞隊列具有更高的吞吐量。創(chuàng)建個交易者實例,將自己出售的訂單放入隊列中,每個出售訂單都將會有隨機的交易量。要使用基于優(yōu)先級的隊列,需要提供適當(dāng)?shù)谋容^器。 阻塞隊列 在阻塞隊列的幫助下,許多同步問題都可以被公式化。阻塞隊列是隊列,當(dāng)線程試圖對空隊列進行出列操作,或試圖向滿的隊列中插入條目時,隊列就會阻塞。直到...

    30e8336b8229 評論0 收藏0
  • 在Java中使用Callable、Future進行并行編程

    摘要:使用進行并行編程在中進行并行編程最常用的方式是繼承類或者實現(xiàn)接口。從開始提供了和兩個接口,通過使用它們可以在任務(wù)執(zhí)行完畢后得到執(zhí)行結(jié)果。 使用Callable、Future進行并行編程 在Java中進行并行編程最常用的方式是繼承Thread類或者實現(xiàn)Runnable接口。這兩種方式的缺點是在任務(wù)完成后無法直接獲取執(zhí)行結(jié)果,必須通過共享變量或線程間通信,使用起來很不方便。從Java 1....

    kgbook 評論0 收藏0
  • 模擬病毒掃描程序(Executors、ScheduledExecutorService

    摘要:類重點是那個病毒掃描程序的例子,認(rèn)真看三遍。會從線程池中選擇線程,并將對象提交給線程任務(wù)。比如病毒掃描,你可以使用類實現(xiàn)的執(zhí)行器服務(wù),每小時運行一次病毒掃描。該應(yīng)用是以固定頻率執(zhí)行的病毒掃描程序。 Executors類 重點是那個病毒掃描程序的例子,認(rèn)真看三遍。本文花了四個小時。 GitHub代碼歡迎star。 小白認(rèn)為學(xué)習(xí)語言最好的方式就是模仿、思考別人為什么這么寫。結(jié)合栗子效果更好...

    antz 評論0 收藏0
  • java高并發(fā)系列 - 第19天:JUC中Executor框架詳解1,全面掌握java并發(fā)相關(guān)技術(shù)

    摘要:有三種狀態(tài)運行關(guān)閉終止。類類,提供了一系列工廠方法用于創(chuàng)建線程池,返回的線程池都實現(xiàn)了接口。線程池的大小一旦達(dá)到最大值就會保持不變,在提交新任務(wù),任務(wù)將會進入等待隊列中等待。此線程池支持定時以及周期性執(zhí)行任務(wù)的需求。 這是java高并發(fā)系列第19篇文章。 本文主要內(nèi)容 介紹Executor框架相關(guān)內(nèi)容 介紹Executor 介紹ExecutorService 介紹線程池ThreadP...

    icattlecoder 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<