package xqlee.net.project.demo.thread.synchronize;
public class ForTest {
public static int count = 0;
public static void main(String[] args) {
// 开启两个线程
for (int i = 0; i < 2; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
//每个线程累计加100
for (int j = 0; j < 100; j++) {
count++;
// System.out.println(count);
}
}
}).start();
}
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("count=" + count);
}
}
疑惑:最终输出的count结果是多少呢?两个线程执行完毕一定是200吗?package xqlee.net.project.demo.thread.synchronize;
public class ForTest {
public static int count = 0;
public static void main(String[] args) {
// 开启两个线程
for (int i = 0; i < 2; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
//每个线程累计加100
for (int j = 0; j < 100; j++) {
synchronized (ForTest.class) {
count++;
}
// System.out.println(count);
}
}
}).start();
}
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("count=" + count);
}
}
所谓原子操作类,指的是java.util.concurrent.atomic包下,一系列以Atomic开头的包装类。例如AtomicBoolean,AtomicInteger,AtomicLong。它们分别用于Boolean,Integer,Long类型的原子性操作。
现在我们尝试在代码中引入AtomicInteger类:
package xqlee.net.project.demo.thread.synchronize;
import java.util.concurrent.atomic.AtomicInteger;
public class ForTest2 {
public static AtomicInteger count = new AtomicInteger(0);
public static void main(String[] args) {
// 开启两个线程
for (int i = 0; i < 2; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
//每个线程累计加100
for (int j = 0; j < 100; j++) {
count.incrementAndGet();
// System.out.println(count);
}
}
}).start();
}
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("count=" + count);
}
}
什么是CAS?
CAS是英文单词Compare And Swap的缩写,翻译过来就是比较并替换。
CAS机制当中使用了3个基本操作数:内存地址V,旧的预期值A,要修改的新值B。
更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B。
这样说或许有些抽象,我们来看一个例子:
1.在内存地址V当中,存储着值为10的变量。
1.CPU开销较大
在并发量比较高的情况下,如果许多线程反复尝试更新某一个变量,却又一直更新不成功,循环往复,会给CPU带来很大的压力。
2.不能保证代码块的原子性
CAS机制所保证的只是一个变量的原子性操作,而不能保证整个代码块的原子性。比如需要保证3个变量共同进行原子性的更新,就不得不使用Synchronized了。
3.ABA问题
这是CAS机制最大的问题所在。
什么是ABA问题?怎么解决?我们后面来详细介绍。
http://blog.xqlee.com/article/343.html