看了一段程序,大概是spring定时任务,自动执行一段代码,为了线程安全加了锁。
贴一段代码:
List> hashMapList = null;
IsCompleteClient isCompleteClient = new IsCompleteClient();
synchronized (mutexLock) {
hashMapList = isCompleteClient.notifyResult();
}
想知道锁一个空的mutexLock对象的目的是什么?
不应该是:
IsCompleteClient isCompleteClient = new IsCompleteClient();
synchronized (isCompleteClient) {
list = isCompleteClient.notifyResult();请问两种写法有什么区别?
http://www.cnblogs.com/devinzhang/archive/2011/12/14/2287675.html
里面说到了
上面的这个例子比原文给出的例子要好一些,因为原文中的加锁是针对类定义的,一个类只能有一个类定义,而同步的一般原理是应该尽量减小同步的粒度以到达更好的性能。笔者给出的范例的同步粒度比原文的要小。
首先,这个锁对象应该不是由定时任务类创建的,而是定时任务依赖的对象的一个属性,那么定时任务在访问该共享对象的时候,锁就会起作用了。就是这个类所在的对象,该对象实例化的时候就会创建一个IsCompleteClient对象。
其次,你这个锁的mutexLock对象应该是该类的一个成员属性,不可能是空对象的,否则会报空指针异常的。
最后,你这两种方式在共享资源上的锁是不同的,那么就会存在一个问题,如果两个线程同时分别获取这两种锁,他们就可能同时操作同一个共享对象了。所以Java并发编程实践里面提出:被包含的对象只能通过持有特定的锁来访问。
有一本由JDK源码的并发包的作者们联合出版的关于Java并发的书,叫《Java并发编程实践》,真正能很好的帮助Java开发人员了解并发的应用,推荐楼主看看。真正的Java大牛,书也很好。