2013-11-11 4 views
0

Рассмотрите следующий сценарий.Не нужно ли компилятору Java синхронизировать?

public synchronized String getData(){ 
    return getInfo(); 
} 
private String getInfo(){     
    // operation here should synchronized 
    return "Synchronize Info"; 
} 

Если кто-то пропускает поток этой операции. Система может стать нестабильной, если компилятор Java заставит сделать getInfosynchronized таких проблем не будет. Но Java-компилятор не делает этого. Теперь разработчик должен отвечать за make getInfosynchronized или нет. Почему Java не вынуждает делать getInfosynchronized?

+0

Возможный дубликат: http://stackoverflow.com/questions/9525882/if-a-synchronized-method-calls-another-non-synchronized-method-is-there-a-lock – sinelaw

+0

Синхронизация происходит по цене. –

+0

@frostjogla, кто сказал, что компилятор пишет код? Если у вас нет идеи, оставьте ее в покое. Лучше смотреть иначе, чем что-то писать. –

ответ

1

Из документации Java по адресу http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html «невозможно, чтобы два вызова синхронизированных методов на одном объекте чередовали».

Другими словами, если вы звоните getData, то любые будущие звонки на getData на том же объекте будут ждать, пока это не будет сделано. Таким образом, даже когда поток управления перемещается в getInfo, система все равно будет блокировать любые будущие вызовы до getData до тех пор, пока первые не вернутся, поэтому нет причин, по которым getInfo должен быть заблокирован. Надеюсь, это поможет!

+0

Я думаю, дело в том, что какой-то другой метод, который не синхронизирован, может случайно вызвать 'getInfo' (который предположительно чувствителен к синхронности), хотя я не уверен, что ожидает OP. В этом я поставил синхронизированное ключевое слово на 'getInfo', а также – sinelaw

+0

да - в этом примере он говорит компилятору, что работа, выполняемая в getData, чувствительна к синхронизации, но не такая getInfo. Таким образом, компилятор будет применять его в getData, но getInfo все равно может выполняться одновременно. – mattdee123

2

Невозможно, чтобы компилятор Java мог эффективно использовать это. Вы можете придумать правило, согласно которому синхронизированные методы могут вызывать только методы одного и того же объекта, если они синхронизированы, но это не полезно, кроме как в довольно узких сценариях. Если getInfo() были общедоступными, getData() может легко вызвать другой класс, который переводит обратно на getInfo() на исходный объект.

Кроме того, синхронизация может использоваться для отдельных операторов, а не для целых методов, а также есть other locks. Попытка разработать правила компилятора для предотвращения синхронизации кода с использованием несинхронизированных данных для всех этих случаев была бы сложной или невозможной.

На самом деле, законно хотеть вызывать метод без стоимости синхронизации в моменты, когда известно, что только поток использует объект. Решая, какие части объекта должны быть заблокированы, и когда это сложная проблема дизайна, которую может сделать только программист-программист.

Так что Java не может/не помешает вам писать код, который не является безопасным. Это все равно. Если под «системой» вы подразумеваете «компьютер», он не станет «неустойчивым». В худшем случае этот класс будет ошибкой.

Смежные вопросы