锁之我见

锁总述:拥有的线程才能进入同步代码块

 

1.为了保证修改不中断,别的线程不插入,这种锁对象往往是OBJECT成员实例,

如:

    public void println(boolean x) {
	synchronized (lock) {//这里加锁,保证以下两个方法不中断
	    print(x);
	    println();
	}
    }

2.避免读到别的线程放入的脏数据

### Java 偏向机制及原理 #### 什么是偏向? 偏向是一种针对无竞争场景下的优化技术。在大多数情况下,对象的只会被同一个线程多次获取而不会发生竞争。为了减少不必要的同步开销,JVM 引入了偏向的概念[^3]。当一个线程首次访问某个对象时,如果该对象尚未定,则 JVM 将此线程的 ID 记录到对象头中的 Mark Word 部分,并设置偏向标志位为 1。此后,同一线程再次访问该对象时无需执行加操作,只需验证 Mark Word 中存储的线程 ID 是否与当前线程匹配即可[^4]。 这种设计极大地减少了无竞争情况下的同步成本,因为不需要频繁地调用操作系统级别的互斥原语(如 CAS 或者信号量)。然而,一旦其他线程试图访问已被偏向前述线程的对象,就会触发偏向撤销流程,进而升级为更高级别的状态(例如轻量级或重量级)[^2]。 #### 偏向的工作流程 以下是偏向的主要工作流程: 1. **初始化阶段**:新建对象时,Mark Word 初始化为空闲状态,表示没有任何线程持有该。 2. **初次加**:第一个线程尝试对该对象加时,如果没有检测到已有线程占用,则将自己的 Thread ID 写入 Mark Word 并标记为偏向模式。 3. **后续重入**:同一线程重复访问已偏向自己的对象时,仅需比较 Mark Word 中保存的 Thread ID 即可确认是否拥有权限,省去了复杂的加解逻辑。 4. **竞争发生**:若有第二个线程请求相同对象上的资源,则原有偏向会被撤销,转而采用更加严格的策略以应对并发冲突情形。 5. **撤销过程**:偏向撤消是一个相对耗时的过程,因为它涉及到全局安全点暂停所有活动线程的操作。在此期间,受影响的对象将重新评估其级别并向更高形态演进[^4]。 #### 示例分析 考虑如下代码片段: ```java public abstract class User { public static void testSync() { synchronized (User.class) { System.out.println("我是"); } } public static void main(String[] args) { User.testSync(); } } ``` 在这个例子中,`synchronized(User.class)` 使用的是静态方法层面的类加载器。假设只有一个主线程运行这段程序,那么按照默认配置,JVM 可能会对 `User.class` 进行偏向处理。也就是说,第一次进入临界区之前,JVM 把当前线程的信息嵌入到了 `User.class` 对应的 Monitor 结构里面去。之后只要还是这条单线程路径继续往下走的话,就不需要再经历完整的监视器协议握手动作了[^1]。 不过要注意的是,实际开发环境中,尤其是现代 JDK 版本里边,默认启用了诸如 `-XX:-UseBiasedLocking=false` 参数关闭偏向特性的情况越来越多见,这是考虑到高吞吐量服务端应用场景下可能存在大量短生命周期临时对象或者高度争抢热点数据区域的缘故所致[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值