refactor the code, add lock protection