Bigdecimal多线程做除法导致的一系列问题

本文详细探讨了在Java中使用BigDecimal进行除法运算时,如何正确设置精度以避免出现Non-terminating decimal expansion异常。通过对比不同的除法实现方式,阐述了在devide方法中直接设置精度的重要性。

        在使用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);
            }
        });
    }
    
    ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值