Может ли кто-нибудь объяснить мне, какие преимущества и недостатки двух разных подходов?
Java, похоже, поддерживает изменчивые поля типа long, а С# - нет. Каковы причины этого?
Ответ 1
Когда a double
или long
в Java volatile
, & sect; 17.7 Спецификации Java Language требует, чтобы они считываются и записываются атомарно. Когда они нестабильны, они могут быть записаны в нескольких операциях. Это может привести, например, к верхним 32 битам длинного, содержащему новое значение, тогда как нижние 32 бита все еще содержат старое значение.
Атомные чтения и записи проще программисту рассуждать и писать правильный код. Тем не менее, поддержка атомных операций может наложить нагрузку на разработчиков ВМ в некоторых средах.
Ответ 2
Я не знаю, почему volatile не может применяться к 64-битным ints в С#, но вы можете использовать Thread.VolatileWrite для сделайте то, что вы хотите на С#. Ключевое слово volatile - это просто синтаксический сахар на этом вызове.
выдержка:
Примечание: В С# использование изменчивого модификатора в поле гарантирует, что весь доступ к этому полю использует Thread.VolatileRead или Thread.VolatileWrite.
Синтаксический сахар (ключевое слово) применяется к 32-битным ints, но вы можете использовать фактические вызовы методов для 64-битных ints.
Ответ 3
Я предполагаю, что это сводится к тому, что может гарантировать модель памяти. Я не знаю огромной суммы о модели памяти CLI (что С# должен использовать), но я знаю, что это будет гарантировать 32 бита... но не 64 (хотя это будет гарантировать 64-битную ссылку на x64 - полные правила приведены в §17.4.3 ECMA 334v4). Так что это не может быть volatile
. У вас все еще есть методы Interlocked
(например, long Interlocked.Exchange(ref long,long)
и long Interlocked.Increment(ref long)
и т.д.).
Ответ 4
Я предполагаю, что longs не могут быть volatile в С#, потому что они больше 32 бит и не могут быть доступны в атомной операции. Несмотря на то, что они не будут храниться в кэше регистров или процессоров, поскольку для чтения или записи значения для одного потока может потребоваться несколько операций, чтобы один поток мог прочитать значение, а другое - в процессе его записи.
Я считаю, что существует разница между тем, как Java реализует изменчивые поля и как работает DotNet, но я не уверен в деталях. Java может использовать блокировку в поле, чтобы предотвратить проблему, с которой имеет С#.