У меня есть три различных класса:Какие блоки кода должны быть синхронизированы?
- управляемый компонент (
singleton
сфера) - управляемый компонент (
session
сфера) - Spring
@Controller
Я прочитал несколько постов здесь о синхронизации, но я все еще не понимают, как это должно быть и как это работает.
Короткие примеры:
1) управляемый компонент (singleton
область применения).
Здесь все поля должны быть одинаковы для всех пользователей. Все пользователи работают с одним экземпляром этого объекта или с его копиями (???).
public class CategoryService implements Serializable {
private CategoryDao categoryDao;
private TreeNode root; //should be the same for all users
private List<String> categories = new ArrayList<String>();//should be the same for all users
private List<CategoryEntity> mainCategories = new ArrayList<CategoryEntity>();
//should be the same for all users
public void initCategories() {
//get categories from database
}
public List<CategoryEntity> getMainCategories() {
return mainCategories;
}}
2) управляемый компонент (session
сферы)
В этом случае каждый пользователь имеет свой собственный экземпляр объекта.
Когда пользователь пытается удалить категорию, которую он должен проверить, это другие пользователи, которые пытаются удалить одну и ту же категорию, поэтому нам нужно использовать synchronized
block ???
public class CategoryServiceSession implements Serializable {
private CategoryDao categoryDao;
private CategoryService categoryService;
private TreeNode selectedNode;
public TreeNode getSelectedNode() {
return selectedNode;
}
public void setSelectedNode(TreeNode selectedNode) {
this.selectedNode = selectedNode;
}
public void deleteCategory() {
CategoryEntity current = (CategoryEntity) selectedNode.getData();
synchronized (this) {
//configure tree
selectedNode = null;
categoryDao.delete(current);
}
categoryService.initCategories();
}}
3) Пружина @Controller
Здесь все пользователи могут иметь экземпляр (или каждый пользователь имеет свой собственный экземпляр ???). Но когда какой-то администратор пытается изменить параметр некоторого пользователя, он должен проверить, является ли еще один администратор, пытающийся выполнить ту же операцию?
@Controller
@RequestMapping("/rest")
public class UserResource {
@Autowired
private UserDao userDao;
@RequestMapping(value = "/user/{id}", method = RequestMethod.PUT)
public @ResponseBody UserEntity changeBannedStatus(@PathVariable Long id) {
UserEntity user = userDao.findById(id);
synchronized (id) {
user.setBanned(!user.getBanned());
userDao.update(user);
}
return user;
}
}
Итак, как это должно быть?
Извините за мой английский.
Следовательно, если два процесса пытаются изменить один и тот же «пользователь», этот фрагмент кода «synchronized (id)] {userDao.update (пользователь); } 'не помогает избежать столкновения/ошибки? – DarkFeniks
Нет. Поскольку любой данный экземпляр «пользователь» является локальным, и пользовательский объект в любом случае не совпадает с объектом id. Вы немного смешиваете понятия. – lscoughlin