1.先来个计数器的递增
- UnSafeAdd.java 对线程没采取任何措施
package com.ctgu.juc_project.example.start;
import com.ctgu.juc_project.annotation.NotThreadSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
@NotThreadSafe
@Slf4j
public class UnSafeAdd {
private static int threadCount = 10;
private static CountDownLatch countDown = new CountDownLatch(threadCount);
private static int count = 0;
private static void add(){
for (int i = 0; i < 1000; i++) {
count += 1;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
countDown.countDown();
}
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < threadCount; i++) {
new Thread(UnSafeAdd::add).start();
}
countDown.await();
log.info("count: {}", count);
}
}
- SafeAddWithSyn.java 加锁效率低下
package com.ctgu.juc_project.example.start;
import com.ctgu.juc_project.annotation.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
@ThreadSafe
@Slf4j
public class SafeAddWithSyn {
private static int threadCount = 10;
private static CountDownLatch countDown = new CountDownLatch(threadCount);
private static int count = 0;
private synchronized static void add(){
for (int i = 0; i < 1000; i++) {
count += 1;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
countDown.countDown();
}
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < threadCount; i++) {
new Thread(SafeAddWithSyn::add).start();
}
countDown.await();
log.info("count: {}", count);
}
}
- SafeAddWithAtomic.java 原子变量
package com.ctgu.juc_project.example.start;
import com.ctgu.juc_project.annotation.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
@ThreadSafe
@Slf4j
public class SafeAddWithAtomic {
private static int threadCount = 10;
private static CountDownLatch countDown = new CountDownLatch(threadCount);
private static AtomicInteger count = new AtomicInteger(0);
private static void add(){
for (int i = 0; i < 1000; i++) {
count.incrementAndGet();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
countDown.countDown();
}
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < threadCount; i++) {
new Thread(SafeAddWithAtomic::add).start();
}
countDown.await();
log.info("count: {}", count.get());
}
}
- SafeAddWithStriped64.java 类似于CurrentHashMap的atmoic分段锁
package com.ctgu.juc_project.example.start;
import com.ctgu.juc_project.annotation.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.LongAdder;
@ThreadSafe
@Slf4j
public class SafeAddWithStriped64 {
private static int threadCount = 10;
private static CountDownLatch countDown = new CountDownLatch(threadCount);
private static LongAdder count = new LongAdder();
private static void add(){
for (int i = 0; i < 1000; i++) {
count.increment();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
countDown.countDown();
}
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < threadCount; i++) {
new Thread(SafeAddWithStriped64::add).start();
}
countDown.await();
log.info("count: {}", count);
}
}
2.原子变量数据类型
- AtomicBoolean
- AtomicInteger
- AtomicLong
CAS算法原理: CompareAndSwap(V,E,N)
volatile V; 多线程可见,表示准备要被更新的变量
E表示我们提供的 期望的值
N表示新值 ,准备更新V的值
3.原子变量分段Striped64类
- DoubleAccumlator
- DoubleAddr
- LongAccumulator
- LongAddr
- Striped64
分治的思想,将一个数值分成多个线程持有段Cell,然后同时CAS,最后将分段的值加和。
4.原子变量数组类
- AtomicIntegerArray
- AtomicLongArray
- AtomicReferenceArray
package com.ctgu.juc_project.example.start;
import com.ctgu.juc_project.annotation.NotThreadSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
@Slf4j
@NotThreadSafe
public class UnSafeArray {
private static int threadCount = 10;
private static CountDownLatch countDown = new CountDownLatch(threadCount);
private static int[] values = new int[10];
private static void add(){
for (int i = 0; i < 1000; i++) {
for (int j = 0; j < values.length; j++) {
values[j]++;
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
countDown.countDown();
}
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < threadCount; i++) {
new Thread(UnSafeArray::add).start();
}
countDown.await();
log.info("values: {}", values);
}
}
package com.ctgu.juc_project.example.start;
import com.ctgu.juc_project.annotation.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicIntegerArray;
@Slf4j
@ThreadSafe
public class SafeArray {
private static int threadCount = 10;
private static CountDownLatch countDown = new CountDownLatch(threadCount);
private static int[] values = new int[10];
private static AtomicIntegerArray atomicValues = new AtomicIntegerArray(values);
private static void add(){
for (int i = 0; i < 1000; i++) {
for (int j = 0; j < values.length; j++) {
atomicValues.incrementAndGet(j);
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
countDown.countDown();
}
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < threadCount; i++) {
new Thread(SafeArray::add).start();
}
countDown.await();
log.info("atomicValues: {}", atomicValues);
log.info("values: {}", values);
}
}
5.原子变量引用类型
- AtomicReference
- AtomicMarkableReference 仅标记是否修改过,mark是boolean类型
- AtomicStampedReference 时间戳解决ABA问题
package com.ctgu.juc_project.example.atomic;
import com.ctgu.juc_project.annotation.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.atomic.AtomicReference;
@Slf4j
@ThreadSafe
public class AtomicExample4 {
private static AtomicReference<Integer> count = new AtomicReference<>(0);
public static void main(String[] args) {
count.compareAndSet(0, 2); // 2
count.compareAndSet(0, 1); // no
count.compareAndSet(1, 3); // no
count.compareAndSet(2, 4); // 4
count.compareAndSet(3, 5); // no
log.info("count:{}", count.get());
}
}
6.原子变量字段类型
- AtomicIntegerFieldUpdater
- AtomicLongFieldUpdater
- AtomicReferenceFieldUpdater
package com.ctgu.juc_project.example.atomic;
import com.ctgu.juc_project.annotation.ThreadSafe;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
@Slf4j
@ThreadSafe
public class AtomicExample5 {
private static AtomicIntegerFieldUpdater<AtomicExample5> updater =
AtomicIntegerFieldUpdater.newUpdater(AtomicExample5.class, "count");
@Getter
public volatile int count = 100;
public static void main(String[] args) {
AtomicExample5 example5 = new AtomicExample5();
if (updater.compareAndSet(example5, 100, 120)) {
log.info("update success 1, {}", example5.getCount());
}
if (updater.compareAndSet(example5, 100, 120)) {
log.info("update success 2, {}", example5.getCount());
} else {
log.info("update failed, {}", example5.getCount());
}
}
}
网友评论