模仿CAS算法,将数据从0顺序累加到10
模仿代码:
package leo.casTest;
public class SimulateCas {
// 模仿CAS算法的思想,完成将数据从0顺序累加到10
public static void main(String[] args) {
AtomicsimulateThread atomicsimulateThread = new AtomicsimulateThread();
for (int i = 0; i < 10; i++){
Thread thread = new Thread(atomicsimulateThread);
thread.start();
}
}
}
// 每个线程的任务就是将数字+1
class AtomicsimulateThread implements Runnable {
@Override
public void run() {
while (true){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
// aValue对应的是CAS中线程缓存中的值
int aValue = CasSimulate.getvValue();
// bValue对应的是CAS中线程拟更新的值
int bValue = aValue + 1;
synchronized (AtomicsimulateThread.class){
// 这里是第二次读取主存中的数据,如果和线程缓存中的一致,那么就直接更新,
// 这里读取和更新的操作需要是原子性的,所以加了synchronized锁
int vvalue = CasSimulate.getvValue();
if (vvalue >= 10){
return;
}
if (aValue != vvalue){
continue;
}
CasSimulate.setvValue(bValue);
// 使用方法进行累加
System.out.println("线程: " + Thread.currentThread().getName() + "将数据变为: " + bValue);
return;
}
}
}
}
// 公共资源类,vValue代表公共资源
class CasSimulate{
static volatile int vValue = 0;
public static int getvValue() {
return vValue;
}
public static void setvValue(int vValue) {
CasSimulate.vValue = vValue;
}
}
执行结果:
总结:
- 按照CAS的思路,做出了A(线程缓存的数据)、B(线程拟修改的新值)、V(主存中的数据)三种意义的变量,通过这三种变量进行比较、更新来保证数据的原子性;
- 因为从0累增到10需要10个线程,所以只创建了10个线程,没有造成资源浪费;
- 在当前线程的A与主存的V不匹配的时候,更新当前线程的A和B,这一条思路也模仿到位了;
- 不过还是好慢呀,也太慢太慢了吧QAQ。
优化模仿CAS算法
优化后的代码:
package leo.casTest;
public class OptimisticSimulateCas {
// 模仿CAS算法的思想,完成将数据从0顺序累加到10
public static void main(String[] args) {
OptimisticAtomicSimulateThread optimisticAtomicSimulateThread = new OptimisticAtomicSimulateThread();
for (int i = 0; i < 10; i++){
Thread thread = new Thread(optimisticAtomicSimulateThread);
thread.start();
}
}
}
// 每个线程的任务就是将数字+1
class OptimisticAtomicSimulateThread implements Runnable {
@Override
public void run() {
while (true){
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
int aValue = OptimisticCasSimulate.getvValue();
if (!OptimisticCasSimulate.compareAndUpdate(aValue)){
this.run();
return;
}
return;
}
}
}
// 公共资源类,vValue代表公共资源
class OptimisticCasSimulate{
static volatile int vValue = 0;
public static synchronized int getvValue() {
return vValue;
}
public static synchronized void setvValue(int vValue) {
OptimisticCasSimulate.vValue = vValue;
}
synchronized static boolean compareAndUpdate(int aValue) {
vValue = OptimisticCasSimulate.getvValue();
if (aValue != vValue) {
return false;
}
OptimisticCasSimulate.setvValue(vValue + 1);
System.out.println("线程:" + Thread.currentThread().getName() + "将数据变为: " + OptimisticCasSimulate.getvValue());
return true;
}
}
优化后的执行结果:
优化了哪些地方?
- 减少了线程休眠的时间;
- 将同步锁代码块移到了公共资源类里面,更贴合CAS算法的思想,就是不阻塞线程,不过也没办法完全不阻塞线程呀呀呀…