У CGlib есть одно важное ограничение: целевой класс должен предоставлять конструктор по умолчанию.
Если вы используете инъекцию на основе свойств вместо инъекции на основе конструктора, проблема исчезнет.
Когда double
или long
в Java является изменчивым
, §17.7 Спецификации языка Java требует, чтобы они читались и записывались атомарно. Когда они не изменчивы, их можно записать за несколько операций. Это может привести, например, к тому, что верхние 32 бита длинного числа содержат новое значение, в то время как нижние 32 бита все еще содержат старое значение.
Атомарные операции чтения и записи проще для программиста разобраться и написать правильный код с участием. Тем не мение,
Я не знаю, почему volatile нельзя применить к 64-битным int в C #, но вы можете использовать Thread.VolatileWrite , чтобы делать то, что вы хотите в C #. Ключевое слово volatile - это просто синтаксический сахар для этого вызова.
отрывок:
Примечание: В C # использование модификатора volatile в поле гарантирует, что любой доступ к этому полю использует Thread.VolatileRead или Thread.VolatileWrite.
Синтаксический сахар (ключевое слово) применяется к 32-битным целым числам, но вы можете использовать фактические вызовы методов для 64-битных целых чисел.
Думаю, все сводится к тому, что модель памяти может гарантировать. Я не очень много знаю о модели памяти CLI (которую должен использовать C #), но я знаю, что она гарантирует 32 бита ... но не 64 (хотя это гарантирует 64-битную ссылку на x64 - полные правила приведены в §17.4.3 ECMA 334v4). Так что это не может быть изменчивым
. У вас все еще есть методы Interlocked
(например, long Interlocked.Exchange (ref long, long)
и long Interlocked.Increment (ref long)
и т. Д.) .
Я предполагаю, что длинные значения не могут быть изменчивыми в C #, потому что они больше 32 бит и не могут быть доступны в атомарной операции. Даже если они не будут храниться в регистре или кеше ЦП, поскольку для чтения или записи значения требуется более одной операции, один поток может прочитать значение, в то время как другой находится в процессе его записи.
Я считаю, что существует разница между тем, как Java реализует изменчивые поля, и тем, как это делает DotNet, но я не уверен в деталях. Java может использовать блокировку поля, чтобы предотвратить проблему C #.