Java, кажется, поддерживает энергозависимые поля типа долго, в то время как C# не делает - Каковы причины позади этого?

У CGlib есть одно важное ограничение: целевой класс должен предоставлять конструктор по умолчанию.

Если вы используете инъекцию на основе свойств вместо инъекции на основе конструктора, проблема исчезнет.

10
задан kitsune 8 June 2009 в 21:27
поделиться

4 ответа

Когда double или long в Java является изменчивым , §17.7 Спецификации языка Java требует, чтобы они читались и записывались атомарно. Когда они не изменчивы, их можно записать за несколько операций. Это может привести, например, к тому, что верхние 32 бита длинного числа содержат новое значение, в то время как нижние 32 бита все еще содержат старое значение.

Атомарные операции чтения и записи проще для программиста разобраться и написать правильный код с участием. Тем не мение,

8
ответ дан 3 December 2019 в 19:35
поделиться

Я не знаю, почему volatile нельзя применить к 64-битным int в C #, но вы можете использовать Thread.VolatileWrite , чтобы делать то, что вы хотите в C #. Ключевое слово volatile - это просто синтаксический сахар для этого вызова.

отрывок:

Примечание: В C # использование модификатора volatile в поле гарантирует, что любой доступ к этому полю использует Thread.VolatileRead или Thread.VolatileWrite.

Синтаксический сахар (ключевое слово) применяется к 32-битным целым числам, но вы можете использовать фактические вызовы методов для 64-битных целых чисел.

7
ответ дан 3 December 2019 в 19:35
поделиться

Думаю, все сводится к тому, что модель памяти может гарантировать. Я не очень много знаю о модели памяти CLI (которую должен использовать C #), но я знаю, что она гарантирует 32 бита ... но не 64 (хотя это гарантирует 64-битную ссылку на x64 - полные правила приведены в §17.4.3 ECMA 334v4). Так что это не может быть изменчивым . У вас все еще есть методы Interlocked (например, long Interlocked.Exchange (ref long, long) и long Interlocked.Increment (ref long) и т. Д.) .

5
ответ дан 3 December 2019 в 19:35
поделиться

Я предполагаю, что длинные значения не могут быть изменчивыми в C #, потому что они больше 32 бит и не могут быть доступны в атомарной операции. Даже если они не будут храниться в регистре или кеше ЦП, поскольку для чтения или записи значения требуется более одной операции, один поток может прочитать значение, в то время как другой находится в процессе его записи.

Я считаю, что существует разница между тем, как Java реализует изменчивые поля, и тем, как это делает DotNet, но я не уверен в деталях. Java может использовать блокировку поля, чтобы предотвратить проблему C #.

0
ответ дан 3 December 2019 в 19:35
поделиться