并发编程有哪些特性(三要素)呢?
下文笔者讲述并发变成的特性简介说明,如下所示
并发编程的特性
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;
}
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


