并发编程有哪些特性(三要素)呢?
下文笔者讲述并发变成的特性简介说明,如下所示
并发编程的特性
1.可见性 多个线程操作一个共享变量时, 其中一个线程对变量进行修改后, 其他线程可以立即看到修改的结果 2.有序性 程序的执行顺序按照代码的先后顺序来执行 3.原子性 一个或多个操作, 要么全部执行并且在执行的过程中不被其他操作打断, 要么就全部都不执行 类似sql的事务
保证原子性的方法
方式1: 使用局部变量 局部变量存储于栈中 线程私有 不存在变量共享 就不存在线程之间的影响 方式2: 加锁 使用synchronized或lock进行加锁 使用synchronized 2.1 有synchronized修饰方法 2.2 synchronized(lock) 2.3 synchronized(Xxx.class) 使用Lock 则可使用ReentrantLock进行加锁 public class TestClassUtils { //同步锁 private static Object lock = new Object(); private volatile static TestClassUtils instance; public static TestClassUtils getInstance() { if (instance == null) { synchronized (TestClassUtils.class) { if (instance == null) { instance = new TestClassUtils(); } } } return instance; } public static synchronized String getOrderId(String title, int size) { String tradeNo = DateFormatUtils.format(new Date(), DATE_FORMAT); tradeNo += RandomStringUtils.randomNumeric(size); return title + tradeNo; } public static String getOrderId2(String title, int size) { String tradeNo = DateFormatUtils.format(new Date(), DATE_FORMAT); synchronized (lock) { tradeNo += RandomStringUtils.randomNumeric(size); } return title + tradeNo; } } 使用lock private final transient ReentrantLock lock = new ReentrantLock(); public boolean offer(E e) { final ReentrantLock lock = this.lock; lock.lock(); try { System.out.println("线程获得了锁"); return true; } finally { lock.unlock(); System.out.println("线程释放了锁"); } } lock和synchronized区别 一个是手动挡 一个是自动档 Lock这种手动挡的自由度更大 lock可有更多的操作 lock.lock()一直等待到拿的到锁 lock.tryLock()拿不到值会直接返回false 能获取锁,则返回true
可见性的处理方法
禁用缓存 使用volatile关键字 为提高CPU的处理速度 CPU一般不直接跟内存进行通信 而将数据读到内部缓存 被volatile修饰的变量一旦发生修改 CPU嗅探在总线上传播的数据来检查自己的缓存是否失效 会使得自身工作内存失效掉 从而去主内存重新获取新值
有序性的处理方法
为提高CPU处理速度 一般会对指令进行重排序 volatile还可以确保指令重排序时 内存屏障前后的指定不会互串 //使用场景 // //读写锁、状态位(多个线程根据状态位来执行操作) volatile Integer a; //可以实现一写多读的场景 //保证并发修改数据时的正确 set(Integer c) { synchronized(this.a) { this.a = c; } } get() { return a; }
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。