Кажется, что Java поддерживает изменяемые поля типа long, а C # - нет. Каковы причины этого? - PullRequest
10 голосов
/ 09 июня 2009

Может кто-нибудь объяснить мне, каковы преимущества и недостатки двух разных подходов?

Ответы [ 4 ]

8 голосов
/ 09 июня 2009

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

Для атомарного чтения и записи программисту легче рассуждать и писать правильный код. Однако поддержка атомарных операций может наложить нагрузку на разработчиков виртуальных машин в некоторых средах.

7 голосов
/ 09 июня 2009

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

выдержка:

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

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

5 голосов
/ 09 июня 2009

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

0 голосов
/ 09 июня 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...