【Java多线程】volatile关键字【随笔,持续更新】

本文探讨了volatile关键字在Java多线程中的两大作用:确保内存和线程间的可见性,以及防止指令重排序。通过举例分析,解释了为何在特定场景下使用volatile的必要性,并提到了其在实现线程同步时与synchronized的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

volatile关键字的两大作用

1.保证内存、线程间可见

面试题:
实现一个容器,提供两个方法,add、size。 写两个线程,线程1添加10个元素到容器中,线程2实现监控元素的个数,当个数数到5个时,线程2给出提示并结束

public class TestOne {
    //volatile保证线程间可见,使t2能够得到通知
//    volatile List list = new ArrayList();
    //synchronizedList保证线程同步
    volatile List list = Collections.synchronizedList(new LinkedList<>());
    public void add(Object o){
        list.add(o);
    }
    public int size(){
        return list.size();
    }


    public static void main(String[] args) {
        TestOne to = new TestOne();
        new Thread(()->{
            for (int i=0;i<10;i++){
                Object o = new Object();
                to.add(o);
                System.out.println("add"+i);
  //              try {
   //                 TimeUnit.SECONDS.sleep(1);
   //             } catch (InterruptedException e) {
   //                 e.printStackTrace();
 //               }
            }
        },"t1").start();

        new Thread(()->{
            while(true){
                if (to.size()==5) {
                    System.out.println("到5了");
                    break;
                }
            }
            System.out.println("t2结束");
        },"t2").start();
    }
}
  • 分析:
    假如不加volatile关键字线程间不可见,while(true)中的方法永远监测不到,会一直循环运行下去。volatile修饰引用值,引用对象指向另外一个new出来的对象,如果这个对象成员变量里面的值改变了,是观察不到的,所以以上代码不合适。
    可以利用synchronized锁的wait()、notify()来实现
public class TestOne {
    //volatile保证线程间可见,使t2能够得到通知
    volatile List list = new ArrayList();
    //synchronizedList保证线程同步
//    volatile List list = Collections.synchronizedList(new LinkedList<>());
    public void add(Object o){
        list.add(o);
    }
    public int size(){
        return list.size();
    }


    public static void main(String[] args) {
        TestOne to = new TestOne();
        Object lock = new Object();
        new Thread(()-> {
            synchronized (lock) {
                System.out.println("t2启动");
                if (to.size() != 5) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("到5了 t2结束");
                lock.notify();
            }

        },"t2").start();

        new Thread(()->{
            synchronized (lock){
                System.out.println("t1启动");
                for (int i=0;i<10;i++){
                    Object o = new Object();
                    to.add(o);
                    System.out.println("add"+i);
                    if (to.size()==5){
                        lock.notify();  //notify()不释放锁 使得t2拿不到lock 一直处于等待状态
                        try {
                            lock.wait();    //利用wait()将锁释放 t2成功拿到锁 继续执行
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

        },"t1").start();
    }
}
2.禁止指令重排序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值