使⽤ volatile 、 final 、 synchronized 等关键字来实现多线程下的同步(附代码)

文章介绍了在Java中如何使用volatile保证变量在多线程环境中的可见性,final确保变量的不可变性以实现线程安全,以及synchronized关键字实现方法级别的同步,防止数据竞争。

目录

使用volatile关键字实现变量的可见性:

使用final关键字来保证变量的不可变性:

使用synchronized关键字来实现方法级别的同步:


在多线程程序中,为了保证线程安全,需要使用同步机制来避免数据竞争和并发访问问题。Java中提供了一些关键字和API来实现线程同步,其中包括volatile、final和synchronized等。下面是一些例子:

  1. 使用volatile关键字实现变量的可见性:

    public class VolatileExample {
        private volatile boolean isRunning = true;
        
        public void stop() {
            isRunning = false;
        }
        
        public void run() {
            while (isRunning) {
                // do something
            }
        }
    }

    在上面的例子中,isRunning变量被声明为volatile,这意味着它的值在所有线程之间是可见的。如果一个线程修改了isRunning的值,其他线程也会立即看到该值的变化。因此,当stop方法被调用时,run方法中的循环会立即停止。

  2. 使用final关键字来保证变量的不可变性:

### Java `volatile` 关键字多线程编程中的作用 #### 可见性 当多个线程访问共享变量时,为了提高性能,每个线程可能会把该变量缓存在本地内存中。这可能导致某些线程看到的是过期的数据副本而不是最新的数据。使用 `volatile` 修饰符可以确保任何对该字段的更新都会立即写回到主存,并且每次读取都从主存获取最新值,从而解决了不同线程间的工作内存不一致的问题[^2]。 ```java public class VolatileExample { private volatile boolean isRunning = true; public void stop() { this.isRunning = false; } public void doTask() { while (isRunning) { // 执行任务... } } } ``` 上述例子展示了如何利用 `volatile` 来控制循环条件的安全退出,防止由于工作内存与主存之间的差异而导致的任务无法停止的情况发生。 #### 原子性 需要注意的是,尽管 `volatile` 提供了可见性的保障,但它并不提供操作上的原子性保护。这意味着像递增 (`i++`) 或者复合赋值语句这样的动作并不是原子化的,仍然可能存在竞态条件的风险。因此,在涉及复杂状态变化的地方应考虑采用更严格的同步措施,比如 `synchronized` 方法/块或是借助并发包下的工具类[^4]。 ```java // 错误示范:非原子操作即使加上 volatile 也无法保证正确性 private volatile int counter = 0; void incrementNonAtomic() { counter++; // 非原子操作 } // 正确做法之一:使用 synchronized 实现原子化 private final Object lock = new Object(); void incrementSafelyWithSync() { synchronized(lock){ ++counter; } } ``` #### 使用场景 - **标志位**:用于表示某种状态的变化,如上面提到的例子那样作为终止信号。 - **双重检查锁定模式(DCL)** 中的部分实现细节也需要依赖于 `volatile` 的特性来避免指令重排序带来的问题。 - 当只需要简单的布尔型或其他基本类型的即时通知而不需要复杂的逻辑判断时适用。 #### 最佳实践 1. 尽量只对那些确实需要跨线程通信的状态标记应用 `volatile` 属性; 2. 对于复合的操作(例如先读再写的组合),应该优先选用更高层次的同步手段而非单纯依靠 `volatile`; 3. 如果业务需求涉及到大量频繁的竞争资源,则建议评估是否有必要引入更加高效专业的并发结构或算法替代传统锁机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值