Если вам нужен простой синхронный конечный автомат, в котором не более одного выполнения происходит в любой данный момент времени, я думаю о следующей модели:
1) Контекст выполнения представлен объектом Context. Контекст передается между состояниями и используется менеджером для принятия решения о потоке. API контекста зависит от того, насколько универсальной должна быть система.
2) Интерфейс состояния содержит метод execute (Context), в котором имеет место определенная логика. Разрешено использовать и изменять данные контекста.
3) Менеджер настроен с правилами перехода. Он может определить следующее состояние для выполнения, учитывая последнее состояние и контекст. Он начинается с выполнения начального состояния. После каждого выполнения состояния S он проверяет объект контекста на соответствие правилам перехода, связанным с состоянием S. Когда он достигает состояния терминала, поток завершается.
При таком дизайне реализации состояний никоим образом не знают о диспетчере и не участвуют в принятии решений о маршрутизации.