上面提到了加锁机制,AtomicInteger 可以通过原子操作实现加锁,同时,java 提供了一种“内置锁”机制,也就是 synchronized 关键字:
synchronized (lock) {
// 访问或修改由锁保护的共享状态
}
可重入
提到加锁,就要说说死锁,众所周知,对一个锁变量两次获取锁就会引发死锁,因为他想要得到的锁已经被自己持有,他只能等待持有者释放,而他自己因为等待而无暇释放已经占有的锁
synchronized 关键字通过可重入的方式解决了这个问题,每个线程如果在已经持有内置锁的情况下请求同一把锁,他将正常的进入被锁的代码
活跃性与性能
使用加锁的机制来进行线程同步,最大的问题就是线程活跃性,如何保证系统的性能?
此前我的一篇博客中提到,在 java 通过原生的 org.rabbit.client 包来操作 rabbitmq 时,多个线程同时使用一个共享的 connection 创建 channel,由于这一过程被 synchronized 加锁,致使同一时间有大量线程在等待锁的释放,而造成整个系统耗时过长,请求失败率接近 50%