Общее использование classloaders должно изолировать JAR. Если у Вас есть приложение, которое использует плагины ( Eclipse, Знаток 2 ), то у Вас может быть эта ситуация: Плагин, который X потребностей сотрясают с версией 1.0, в то время как плагин Y нужна та же банка, но версия 2.0. X не работает с версией 2.0, все же.
, Если у Вас есть classloaders, можно создать разделы классов (думайте об изолированных островах, соединенных тонкими мостами; мосты являются classloaders). Таким образом, classloaders может управлять тем, что видит каждый плагин.
, Когда плагин X инстанцирует класса Foo, который имеет статические поля, это не проблема и не будет путаницы с "тем же" классом в плагине Y, потому что каждый classloader на самом деле создаст свой собственный экземпляр класса Foo. У Вас затем есть два класса в памяти, где cl1.getName().equals(cl2.getName())
true
, но cl1.equals(cl2)
не. Это означает, что экземпляры cl1 не являются присвоением, совместимым с экземплярами cl2. Это может привести к странному ClassCastExceptions
, которые говорят, что org.project.Foo
не может быть присвоен org.project.Foo
.
Точно так же, как с удаленными островами, эти два класса не знают, что другой существует. Думайте о человеческих клонах, которые рождаются и затем повышены на различных островах. С точки зрения VM нет никакой проблемы, потому что экземпляры Класса типа обрабатываются как любой другой объект: может быть несколько из них. То, что Вы думаете, что некоторые из них являются "тем же", не имеет значения для VM.
Другое использование для этого шаблона состоит в том, что можно избавиться от классов, загрузил этот путь: Просто удостоверьтесь, что ни у кого нет указателя ни на какой объект, созданный из классов, загруженных из classloader, и затем забудьте о classloader, также. На следующем запуске GC, все классы, загруженные этим classloader, удалены из памяти. Это позволяет Вам "перезагружать" свое приложение, не имея необходимость перезапускать целый VM.
Counter.objects.get_or_create(name = name)
Counter.objects.filter(name = name).update(count = F('count')+1)
или использование выражения F :
counter = Counter.objects.get_or_create(name = name)
counter.count = F('count') +1
counter.save( update_fields=["count"] )
Не забудьте указать, какие поля обновлять, Или вы можете столкнуться с условиями гонки в других возможных полях модели!
В официальную документацию добавлен раздел о состоянии гонки , связанный с этим подходом .
Или, если вам нужен только счетчик, а не постоянный объект, вы можете использовать счетчик itertools, который реализован на C. GIL обеспечит необходимую безопасность.
-- Сай