Как Java получает доступ к ресурсам
В Java есть встроенная поддержка предотвращения коллизий при использовании одного типа ресурсов - объектов в памяти. Поскольку элементы данных класса объявляются как private
и доступ к этой области памяти возможен только посредством методов, то можно избежать коллизий объявив эти методы как synchronized. Одновременно только один процесс может вызвать synchronized метод для определенного объекта (хотя этот процесс может вызывать более одного синхронизированного метода объекта). Ниже приведены простые synchronized
методы:
synchronized void f() { /* ... */ } synchronized void g(){ /* ... */ }
Каждый объект имеет простой замок (также называемый monitor), который является автоматической частью объекта (т.е. нет необходимости писать специальный код). При вызове любого synchronized метода, этот объект блокируется и ни один другой synchronized метод этого объекта не может быть вызван до тех пор, пока первый не закончиться и не разблокирует объект. В выше приведенном примере, если f() вызвана для объекта, то g() не может быть вызвана для того же объекта до тех, пока f() не завершится и не снимет блокировку. Таким образом, это единственная (в смысле одна - Прим. пер.) блокировка, используемая всеми synchronized методами отдельного объекта и эта блокировка предотвращает возможность записи в память более чем одному методу в одно и тоже время (т.е. более одного процесса в одно и то же время).
Также существует по одной блокировке на каждый класс (как часть объекта Class для класса), таким образом методы synchronized static могут заблокировать друг друга от одновременного доступа к static данным на много-классовой основе.
Запомните, если вы хотите защитить какие-либо ресурсы от одновременного доступа со стороны нескольких процессов, можно сделать это разрешив доступ к этому ресурсу через synchronized методы.