从C++语法角度理解Java线程锁

做WEB应用不可能不接触到线程锁的问题,尽管背后的原理很简单,但说实话要真正理解并在实践中保持信心不太容易。

许多初学者看到某些代码的同步锁(synchronize关键字)之后,便诚惶诚恐地在自己的类方法里也加上很多不必要的同步锁,甚至开始怀疑单例类在web中的实用价值,这种表现其实是还没有理解同步锁的概念。

首先一个问题是同步“锁”的是什么。在网上一搜,会查到一些言简意赅的解释,如“同步锁的是对象,而不是方法”。它虽然完全正确,但还不足以拉菜鸟上岸,因为必然还会有人问:“方法难道不是对象的方法吗,怎么会有锁了对象却不锁方法的概念?”答案说穿了一文不值,实际上只要是学过C++的人立刻就能明白怎么回事。

C++中的函数(方法)类型是非常丰富的,对于类方法的定义方式也不止一种。一个常见的定义类方法的方式是,在类体内只声明函数名、返回值和参数类型,而真正的函数体代码却放在类定义体外的地方,例如:


class CClass {
private:
int id;
public:
int getId();
void setId(int id);
}

int CClass::getId() {return this.id}
void CClass::setId(int id) {this.id = id}


可以这么说,类方法就是一段过程计算代码而已,只不过这段代码有充分的权限可以访问类成员(字段或其他类方法)。这个概念推到极端的例子就是友元函数,这个与类定义完全无关的,可以被其他类或函数调用的公共函数也可以在经过类定义声明后,具有访问类成员的权限。

回到Java上来,既然方法(函数)除了其名字要让类定义声明之外,其实与公共函数并无太大区别,其代码块也不属于类所有,那么同步锁在锁对象的时候,当然也就没有能力锁到方法上去。因此,单例模式下的对象方法(如许多DAO)并没有什么并发问题,除非涉及到一些公共资源如集合类。在了解了Java程序运行的内存分布我们也能明白,所有类的方法代码都是放在代码区(code segment)中待调用的,同步锁作用的范围是堆空间(heap)中的相应对象,与代码区无关。

那么在方法上加synchronize又是什么意思呢?很简单,就是“在这段代码执行期间,调用这段代码的对象及其所有状态(成员)都被锁定,直到方法执行结束”。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值