java-哪些代码块应该同步?

我有三种不同的课程:

>托管bean(单个作用域)
>托管bean(会话范围)
> Spring @Controller

我在这里阅读了几篇有关同步的文章,但我仍然不了解它应该是什么以及它如何工作.

简短示例:
1)受管bean(单个作用域).
在此,所有用户的所有类字段均应相同.所有用户都使用该对象的一个​​实例或其副本(???).

    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)托管bean(会话范围)
在这种情况下,每个用户都有自己的对象实例.
当用户尝试删除类别时,他应检查是否有其他用户试图删除同一类别,因此我们需要使用同步块???

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)Spring @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;
    }
}

那么,应该如何?

对不起我的英语不好.

解决方法:

在您发布的代码中-不需要特别同步,并且您定义的同步块将不会保护您.默认情况下,控制器作用域为单例.

如果您的单例更改共享对象(主要是它们的字段),则可能应将整个方法标记为已同步.

方法级别的变量和最终参数可能永远不需要同步(至少在您似乎正在使用的编程模型中),因此不必担心.

会话对象主要是通过序列化来保护的,但是如果用户有并发请求,您仍然可以进行数据竞争-您必须想像创造性的方式来处理此问题.

您可能/将在数据库中存在并发问题(多个用户试图同时删除或修改数据库行),但这应由DAO中的悲观或乐观锁定和事务处理策略来处理.

运气.

上一篇:java-具有非阻塞套接字的多线程


下一篇:java-内部如何实现互斥锁