Bigdecimal多線程做除法導致的一系列問題

        在使用Bigdecimal的除法的時候要在devide的時候直接將精度設置好,不要以爲devide以後再跟一個setScale就萬事大吉了,這樣當我們遇到無限循環小數的結果集的時候一樣會導致異常java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result的拋出,

public static void main1(String[] args) {
        ExecutorService executorService = new ThreadPoolExecutor(4,4,60L, TimeUnit.SECONDS,new LinkedBlockingQueue<>());
              /*
        線程1、線程2:
                1、在devide的時候直接指定精度,程序正常運行
        * */
        executorService.submit(new Runnable() {
            @Override
            public   void run() {
                Date date =  new Date();
                System.out.println(Thread.currentThread().getName()+date);
                int i = 1;
                while (i<100000000) {
                    // 1、除不設置精度,遇到無限循環導致線程 wait 陷入全部等待。流程直接無限等待宕機
                   // new BigDecimal(1).divide(new BigDecimal("3")).setScale(2, BigDecimal.ROUND_DOWN);
                    // 2、除設置精度,遇到無限循環會Math包來做精度處理,線程狀態 running
                     new BigDecimal(1).divide(new BigDecimal("3"),2, BigDecimal.ROUND_DOWN);
                    i++;
                }
                Date date1 =  new Date();
                System.out.println(Thread.currentThread().getName()+date1);
            }
        });
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                Date date =  new Date();
                System.out.println(Thread.currentThread().getName()+date);
                int i = 1;
                while (i<100000000) {
                    // 1、除不設置精度,遇到無限循環導致線程 wait 陷入全部等待。
                  //  new BigDecimal(1).divide(new BigDecimal("3")).setScale(2, BigDecimal.ROUND_DOWN);
                    // 2、除設置精度,遇到無限循環會Math包來做精度處理,線程狀態 running
                     new BigDecimal(1).divide(new BigDecimal("3"),2, BigDecimal.ROUND_DOWN);
                    i++;
                }
                Date date1 =  new Date();
                System.out.println(Thread.currentThread().getName()+date1);
            }
        });

        /*
        線程3:
                1、線程內運算 直接 devide ,後續對結果做setScale 會導致線程內異常拋出,且線程外捕獲不到,線程直接wait
        * */
        try {
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    Date date = new Date();
                    System.out.println(Thread.currentThread().getName() + date);
                    int i = 1;
                    while (i < 100000000) {
                        // 1、除不設置精度,遇到無限循環導致線程 wait 陷入全部等待。
                        new BigDecimal(1).divide(new BigDecimal("3")).setScale(2, BigDecimal.ROUND_DOWN);
                        // 2、除設置精度,遇到無限循環會Math包來做精度處理,線程狀態 running
                        // new BigDecimal(1).divide(new BigDecimal("3"),2, BigDecimal.ROUND_DOWN);
                        i++;
                    }
                    Date date1 = new Date();
                    System.out.println( Thread.currentThread().getName()+ date1);
                }
            });
        }catch (Throwable throwable){
        System.out.println(throwable);
    }
        /*
        線程4:
                1、線程內運算 直接 devide ,後續對結果做setScale 會導致線程內異常拋出,在線程內將異常捕獲,並繼續相關操作
        * */
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                Date date =  new Date();
                System.out.println(Thread.currentThread().getName()+date);
                int i = 1;
                while (i<10) {
                    // 1、除不設置精度,遇到無限循環導致線程 wait 陷入全部等待。如果此處線程內部不抓異常拋出會直接陷入
                    try{

                      new BigDecimal(1).divide(new BigDecimal("3")).setScale(2, BigDecimal.ROUND_DOWN);
                    }catch (Throwable throwable){
                        System.out.println(throwable);
                    }
                    // 2、除設置精度,遇到無限循環會Math包來做精度處理,線程狀態 running
                    //new BigDecimal(1).divide(new BigDecimal("3"),2, BigDecimal.ROUND_DOWN);
                    i++;
                }
                Date date1 =  new Date();
                System.out.println(Thread.currentThread().getName()+date1);
            }
        });
    }
    
    ```
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章