技术学习笔记
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode

2.3其它方法

1. volatile 关键字

为了实现变量在多个线程间可见。使得线程从公共堆栈中获取变量,而不是线程私有数据栈。

JVM 在 -sever 模式时为了线程运行效率,线程一直在私有堆栈中获取变量值,而主线程的变量是存储在公共堆栈中,解决这种可见性问题,可以使用 volatile 。

volatile 与 synchronized 的比较:

  • volatile 保证可见性不保证原子性(致命缺点),synchronized 保证原子性但不保证可见性。

  • volatile 只能修饰变量。

  • volatile 不发生阻塞,synchronized 会阻塞。

2. 原子类

多线程使用原子操作访问共享资源时,不需要锁也可保证线程安全(多线程访问同一资源时,不会出现脏读或写失败)。

以下代码,多个线程竞争地访问同一个对象中的 count , 使用原子操作保证了线程安全。

  • CountService.java

    public class CountService extends Thread{
        private AtomicInteger count = new AtomicInteger(0);//原子类
        @Override
        public void run(){
            for (int i = 0; i < 1000; i++){
                System.out.println(Thread.currentThread().getName() + ":" +count.incrementAndGet());//incrementAndGet 方法是原子操作
            }
        }
    }
    
  • Run.java

    public class Run {
        public static void main(String[] args) {
            CountService countService = new CountService();
            Thread t1 = new Thread(countService);
            t1.setName("t1");
            t1.start();
            Thread t2 = new Thread(countService);
            t2.setName("t2");
            t2.start();
            Thread t3 = new Thread(countService);
            t3.setName("t3");
            t3.start();
        }
    }
    

方法间的调用不是原子的(调用多个原子操作,不具有原子性,线程间会出现抢占),需要使用 synchronized 来保证线程安全。