Проблема заключается в том, что каждая из ваших задач синхронизируется с другим объектом при доступе и обновлении общей статической переменной. Это означает, что между рабочими потоками нет взаимного исключения. Это означает, что значение, рассчитанное вашим приложением, может быть непредсказуемым и / или зависящим от платформы. (Если вам не повезет ...)
Один из подходов к исправлению состоит в том, чтобы изменить addMoney
на static synchronized
метод. Это приведет к синхронизации потоков на объекте MyThread.class
. Однако, если вы сделаете это, вы обнаружите, что ваше приложение эффективно однопоточное ... потому что только один из ваших MyThread
экземпляров сможет одновременно выполнить свой метод addMoney
.
Не ясно, что является правильным исправлением, потому что не ясно, что пытается продемонстрировать этот "игрушечный" пример. Но альтернативный подход, о котором я говорил, должен, по крайней мере, надежно вычислять результат.
Вы не должны расширять Thread
. Ваш MyThread
класс должен быть заменен классом, который реализует Runnable
. Здесь вы используете Thread
объект, как если бы он был просто Runnable
. Это плохая идея. ExecutorService
, который вы используете, позаботится о создании потока. Вы должны кормить его "задачами", а не "потоками".