Как известно, треш, угар и shared mutable state являются основными ценностями человека (а для кого не является - тот не человек, например). Посему возникает животрепещущий вопрос
расскажите, как хорошим образом сделать глобальные инварианты для блока кода (в concurrent случае)
например, мы хотим проверить, что на протяжении всего исполнения произвольного блока кода, должно выполняться условие «x > 0». А этот x - это shared mutable state, и его может поменять другой поток, поэтому его недостаточно проверять только на входе метода, нужно проверять каждый чекпоинт («каждую строчку»).
но ведь в джаве нет такой фичи. Можно AOPить целиком методы, но не строчки (а что там генерит компилятор на самом деле вообще не видимо глазу чтобы сказать, что вот на этот минимально неделимый кусок intermediate representation я хочу повесить проверку).
и даже для куска IR у нас может случиться тупо мисалайнмент (direct byte buffers на jdk > 6?), мы прочитаем в x того, чего там и не было вообще, и проверка пойдет билгейцу под хвост (кстати, когда случается мисалаймент в джаве?)
можно навелосипедить это на лямбдах (каждую строчку обернуть в метод) но по понятным причинам это не вариант. Во-первых, оптимизация (заинлайнит или не заинлайнит?). Во-вторых, ну просто задолбаешься писать всю эту писанину вручную
можно запустить проверку в отдельном треде - тоже ведь не вариант, там будет происходить черти что. Да и всё равно мы не можем убить тред по своему желанию (если мы не конченые отморози - тогда можем), и нужно будет подпихнуть в целевой тред точки останова.
Ну можно «макросами» переписать сам исходник и реально обернуть каждую строчку в проверки перед сборкой. Или переписать в байткод?
Как это делают правильные, русские java мужики?
Связанный тред в фейсбуке: https://www.facebook.com/olegchir/posts/1157968160892856