请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

关于synchronized

老师好,我看有些源码,synchronized来锁住要操作的对象来保证对象的并发的,而且一般都是这么用的。比如ConcurrentHashMap中put()锁住节点第一个。

我看到另外一些地方synchronized锁住的是一个final new Object()来保证另外一个对象的并发的,比如Tomcat中的servicesLock,在添加、移除、查找、启动服务时都锁住了这个对象,而其服务的集合简单定义。

private Service services[] = new Service[0];

private final Object servicesLock = new Object();

而且通篇servicesLock只在锁定时用了一下,别的地方都没有使用(包括getset)。

这么做有什么好处吗?


正在回答

1回答

你好,这样加锁,通常是因为:作用的代码块里的代码如果同时被多个线程执行可能会出现问题。

举个例子,ConcurrentHashMap里put方法带锁,HashMap的put方法不带锁。我们都知道,ConcurrentHashMap可以保证线程安全,而HashMap就无法保证线程安全(课程里有重点讲,不知道你是否学到),极端情况下会出现死锁。ConcurrentHashMap能做到线程安全的本质就是在某些不适合多线程同时执行的代码块加了锁。

而synchronized具体要锁到什么程度,就需要根据实际场景分析了。synchronized锁无非课程里介绍那四种形式,不同的方式的根本就是锁的粒度不一样。在满足条件的情况下,尽可能的将锁的范围小一点,可以加快处理速度。分析synchronized的关键主要就在这里了。

0 回复 有任何疑惑可以回复我~
  • 提问者 靈寶 #1
    关于老师讲解的HashMap和concurrentHashMap的区别以及源码我都看过了(老师讲解的很多章节我都对着源码看了),这部分我理解。
    
    我就是不理解tomcat为什么那么操作(锁一个不用的空对象)。我觉得他完全版可以锁定services来执行Service的增删查的,而且数组属于对象,可以变内部而不变地址。tomcat采用锁的空对象内部也有可能被变(当然tomcat内部没有对其进行操作)。
    synchronized的范围以及使用地点都理解。但此处都是针对于锁定一个变量。不同的是一个锁定的是要操作的对象来保证这个对象的安全,另一个是锁定一个常量对象来保证这个对象的安全。
    我想知道他这么写的好处,以及能否把这种写法带到日常中来的可行性。
    回复 有任何疑惑可以回复我~ 2018-06-03 16:38:46
  • Jimin 回复 提问者 靈寶 #2
    贴一下你看到的代码
    回复 有任何疑惑可以回复我~ 2018-06-03 16:39:36
  • 提问者 靈寶 回复 Jimin #3
    变量的定义:
     private Service services[] = new Service[0];
        private final Object servicesLock = new Object();
    查找服务方法:
    @Override
        public Service findService(String name) {
    
            if (name == null) {
                return (null);
            }
            synchronized (servicesLock) {
                for (int i = 0; i < services.length; i++) {
                    if (name.equals(services[i].getName())) {
                        return (services[i]);
                    }
                }
            }
            return (null);
    
        }
    回复 有任何疑惑可以回复我~ 2018-06-03 16:41:39
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信