Java thread mutual exclusion problem

I have two threads, and these two threads An and B are mutually exclusive and are in batch form, so if a thread has not finished executing all the data, it will still have to enter this thread the next time it is executed. And when an interface is called, if no data processing is done by the A _ Magi B thread at this time, insert the data and specify the B thread to execute.

I use the mutual exclusion of the two variables, but there are still thread safety issues. So is there a better way to deal with it.

related code
Thread A:

public class AaHistoryTask extends TimerTask {
     @Override
    public void run() {
        try {
            //,B
            if(AsStatusUtil.getAsSettleRepay()) {
                return;
            }

            boolean hasIdleThreads = false;
            List<FactoringsDbCore.AaHistory.Builder> aahs = Db2Pb.toAaHistory(
                    QueryMethods.queryAaHistory(BATCH_SIZE, null));
            if (aahs.size() > 0) {
                if (!AsStatusUtil.setAsAah(true)) {
                    return;
                }
                logger.info("AaHistoryTask inPutAaHistorySize: " + aahs.size());
            } else {
                //aahfalse
                AsStatusUtil.setAsAah(false);
                return;
            }
            for (FactoringsDbCore.AaHistory.Builder aah : aahs) {
                SUB_AA_HISTORY_TASKS[(int) (Long.parseLong(aah.getAccountId()/*.substring(0,17)*/) % SUB_TASK_COUNT)].addNewAah(aah);
            }
        } catch (Exception e) {
            logger.error("", e);
        }
    }
} 

Thread B:

public class SettleKeeperTask extends TimerTask {

    @Override
    public void run() {
        try {
            //A
            if (AsStatusUtil.getAsAah()) {
                return;
            }

            List<FactoringsDbCore.AccountSum.Builder> ass = Db2Pb.toAccountSum(
                        QueryMethods.queryAccountSumToBeSettle(BATCH_SIZE, null));

            if (ass.size() > 0) {
                if(!AsStatusUtil.setAsSettleRepay(true)) {
                    return;
                }
                logger.info("SettleKeeperTask settle inPutAccountSumSize: " + ass.size());
                //
                SettleRepayKeeper.settle(ass);
            } else {
                //
                List<FactoringsDbCore.Repay.Builder> repayList = Db2Pb.toRepay(
                        QueryMethods.queryRepay(FactoringsDbBase.RepayStatus.RS_REPAYING, 1, null));
                if(repayList.size() > 0) {
                    if(!AsStatusUtil.setAsSettleRepay(true)) {
                        return;
                    }
                    //false
                    SettleRepayKeeper.repay(repayList.get(0), BATCH_SIZE);
                } else {
                    AsStatusUtil.setAsSettleRepay(false);
                }
            }

        } catch (Exception e) {
            logger.error("", e);
        }
    }
}

the AsStatusUtil class is:

public class AsStatusUtil {
    //Btruefalse
    private static boolean asSettleRepay = false;

    //Atruefalse[AAH]
    private static boolean asAah = true;

    public static synchronized boolean getAsSettleRepay() {
        return asSettleRepay;
    }

    public static synchronized boolean getAsAah() {
        return asAah;
    }

    public static synchronized boolean setAsSettleRepay(boolean flag) {
        //Afalse
        if(asAah) {
            return false;
        }
        asSettleRepay = flag;
        return true;
    }

    public static synchronized boolean setAsAah(boolean flag) {
        //Bfalse
        if(asSettleRepay) {
            return false;
        }
        asAah = flag;
        return true;
    }
}
Jul.18,2021
Menu