原子类

1. LongAdder

2. LongAccumulator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
LongAdder longAdder = new LongAdder();

longAdder.increment();
longAdder.increment();
longAdder.increment();
System.out.println(longAdder.sum());

LongAccumulator longAccumulator = new LongAccumulator(new LongBinaryOperator()
{
@Override
public long applyAsLong(long left, long right)
{
return left + right;
}
},0);

longAccumulator.accumulate(1);//1
longAccumulator.accumulate(3);//4
System.out.println(longAccumulator.get());
}
运行结果

3

4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
class ClickNumber //资源类
{
int number = 0;
public synchronized void clickBySynchronized()
{
number++;
}

AtomicLong atomicLong = new AtomicLong(0);
public void clickByAtomicLong()
{
atomicLong.getAndIncrement();
}

LongAdder longAdder = new LongAdder();
public void clickByLongAdder()
{
longAdder.increment();
}

LongAccumulator longAccumulator = new LongAccumulator((x,y) -> x + y,0);
public void clickByLongAccumulator()
{
longAccumulator.accumulate(1);
}

}

/**
* ----costTime: 1762 毫秒 clickBySynchronized: 50000000
* ----costTime: 868 毫秒 clickByAtomicLong: 50000000
* ----costTime: 81 毫秒 clickByLongAdder: 50000000
* ----costTime: 71 毫秒 clickByLongAccumulator: 50000000
* @auther hsf
* 需求: 50个线程,每个线程100W次,总点赞数出来
*/
public class AccumulatorCompareDemo
{
public static final int _1W = 10000;
public static final int threadNumber = 50;

public static void main(String[] args) throws InterruptedException
{
ClickNumber clickNumber = new ClickNumber();
long startTime;
long endTime;

CountDownLatch countDownLatch1 = new CountDownLatch(threadNumber);
CountDownLatch countDownLatch2 = new CountDownLatch(threadNumber);
CountDownLatch countDownLatch3 = new CountDownLatch(threadNumber);
CountDownLatch countDownLatch4 = new CountDownLatch(threadNumber);

startTime = System.currentTimeMillis();
for (int i = 1; i <=threadNumber; i++) {
new Thread(() -> {
try {
for (int j = 1; j <=100 * _1W; j++) {
clickNumber.clickBySynchronized();
}
} finally {
countDownLatch1.countDown();
}
},String.valueOf(i)).start();
}
countDownLatch1.await();
endTime = System.currentTimeMillis();
System.out.println("----costTime: "+(endTime - startTime) +" 毫秒"+"\t clickBySynchronized: "+clickNumber.number);

startTime = System.currentTimeMillis();
for (int i = 1; i <=threadNumber; i++) {
new Thread(() -> {
try {
for (int j = 1; j <=100 * _1W; j++) {
clickNumber.clickByAtomicLong();
}
} finally {
countDownLatch2.countDown();
}
},String.valueOf(i)).start();
}
countDownLatch2.await();
endTime = System.currentTimeMillis();
System.out.println("----costTime: "+(endTime - startTime) +" 毫秒"+"\t clickByAtomicLong: "+clickNumber.atomicLong.get());


startTime = System.currentTimeMillis();
for (int i = 1; i <=threadNumber; i++) {
new Thread(() -> {
try {
for (int j = 1; j <=100 * _1W; j++) {
clickNumber.clickByLongAdder();
}
} finally {
countDownLatch3.countDown();
}
},String.valueOf(i)).start();
}
countDownLatch3.await();
endTime = System.currentTimeMillis();
System.out.println("----costTime: "+(endTime - startTime) +" 毫秒"+"\t clickByLongAdder: "+clickNumber.longAdder.sum());

startTime = System.currentTimeMillis();
for (int i = 1; i <=threadNumber; i++) {
new Thread(() -> {
try {
for (int j = 1; j <=100 * _1W; j++) {
clickNumber.clickByLongAccumulator();
}
} finally {
countDownLatch4.countDown();
}
},String.valueOf(i)).start();
}
countDownLatch4.await();
endTime = System.currentTimeMillis();
System.out.println("----costTime: "+(endTime - startTime) +" 毫秒"+"\t clickByLongAccumulator: "+clickNumber.longAccumulator.get());

}
}


运行结果

—-costTime: 5057 毫秒 clickBySynchronized: 50000000
—-costTime: 823 毫秒 clickByAtomicLong: 50000000
—-costTime: 129 毫秒 clickByLongAdder: 50000000
—-costTime: 102 毫秒 clickByLongAccumulator: 50000000

3. AtomicLong

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
class ClickNumber //资源类
{
int number = 0;
public synchronized void clickBySynchronized()
{
number++;
}

AtomicLong atomicLong = new AtomicLong(0);
public void clickByAtomicLong()
{
atomicLong.getAndIncrement();
}

LongAdder longAdder = new LongAdder();
public void clickByLongAdder()
{
longAdder.increment();
}

LongAccumulator longAccumulator = new LongAccumulator((x,y) -> x + y,0);
public void clickByLongAccumulator()
{
longAccumulator.accumulate(1);
}

}

/**
* @auther hsf
* 需求: 50个线程,每个线程100W次,总点赞数出来
*/
public class AccumulatorCompareDemo
{
public static final int _1W = 10000;
public static final int threadNumber = 50;

public static void main(String[] args) throws InterruptedException
{
ClickNumber clickNumber = new ClickNumber();
long startTime;
long endTime;

CountDownLatch countDownLatch1 = new CountDownLatch(threadNumber);
CountDownLatch countDownLatch2 = new CountDownLatch(threadNumber);
CountDownLatch countDownLatch3 = new CountDownLatch(threadNumber);
CountDownLatch countDownLatch4 = new CountDownLatch(threadNumber);

startTime = System.currentTimeMillis();
for (int i = 1; i <=threadNumber; i++) {
new Thread(() -> {
try {
for (int j = 1; j <=100 * _1W; j++) {
clickNumber.clickBySynchronized();
}
} finally {
countDownLatch1.countDown();
}
},String.valueOf(i)).start();
}
countDownLatch1.await();
endTime = System.currentTimeMillis();
System.out.println("----costTime: "+(endTime - startTime) +" 毫秒"+"\t clickBySynchronized: "+clickNumber.number);

startTime = System.currentTimeMillis();
for (int i = 1; i <=threadNumber; i++) {
new Thread(() -> {
try {
for (int j = 1; j <=100 * _1W; j++) {
clickNumber.clickByAtomicLong();
}
} finally {
countDownLatch2.countDown();
}
},String.valueOf(i)).start();
}
countDownLatch2.await();
endTime = System.currentTimeMillis();
System.out.println("----costTime: "+(endTime - startTime) +" 毫秒"+"\t clickByAtomicLong: "+clickNumber.atomicLong.get());


startTime = System.currentTimeMillis();
for (int i = 1; i <=threadNumber; i++) {
new Thread(() -> {
try {
for (int j = 1; j <=100 * _1W; j++) {
clickNumber.clickByLongAdder();
}
} finally {
countDownLatch3.countDown();
}
},String.valueOf(i)).start();
}
countDownLatch3.await();
endTime = System.currentTimeMillis();
System.out.println("----costTime: "+(endTime - startTime) +" 毫秒"+"\t clickByLongAdder: "+clickNumber.longAdder.sum());

startTime = System.currentTimeMillis();
for (int i = 1; i <=threadNumber; i++) {
new Thread(() -> {
try {
for (int j = 1; j <=100 * _1W; j++) {
clickNumber.clickByLongAccumulator();
}
} finally {
countDownLatch4.countDown();
}
},String.valueOf(i)).start();
}
countDownLatch4.await();
endTime = System.currentTimeMillis();
System.out.println("----costTime: "+(endTime - startTime) +" 毫秒"+"\t clickByLongAccumulator: "+clickNumber.longAccumulator.get());

}
}
运行结果

—-costTime: 4763 毫秒 clickBySynchronized: 50000000
—-costTime: 807 毫秒 clickByAtomicLong: 50000000
—-costTime: 111 毫秒 clickByLongAdder: 50000000
—-costTime: 90 毫秒 clickByLongAccumulator: 50000000

4. AtomicInteger

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class MyNumber
{
AtomicInteger atomicInteger = new AtomicInteger();

public void addPlusPlus()
{
atomicInteger.getAndIncrement();
}
}


/**
* 需求:50个线程,每个线程 执行“+1”操作,执行1000次。
* 最终结果:50*1000=50000
* @auther hsf
* @create 2022-02-25 21:59
*/
public class AtomicIntegerDemo
{
public static final int SIZE = 50;

public static void main(String[] args) throws InterruptedException
{
MyNumber myNumber = new MyNumber();
CountDownLatch countDownLatch = new CountDownLatch(SIZE);

for (int i = 1; i <=SIZE; i++) {
new Thread(() -> {
try {
for (int j = 1; j <=1000; j++) {
myNumber.addPlusPlus();
}
} finally {
countDownLatch.countDown();
}
},String.valueOf(i)).start();
}
//等待上面50个线程全部计算完成后,再去获得最终值
countDownLatch.await();

System.out.println(Thread.currentThread().getName()+"\t"+"result: "+myNumber.atomicInteger.get());
}
}
运行结果

main result: 50000

5. AtomicIntegerArray

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(new int[5]);
//AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(5);
//AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(new int[]{1,2,3,4,5});

for (int i = 0; i <atomicIntegerArray.length(); i++) {
System.out.println(atomicIntegerArray.get(i));
}
System.out.println();

int tmpInt = 0;

// 返回旧值,设置新值
tmpInt = atomicIntegerArray.getAndSet(0,1122);
System.out.println(tmpInt+"\t"+atomicIntegerArray.get(0));

tmpInt = atomicIntegerArray.getAndIncrement(0);
System.out.println(tmpInt+"\t"+atomicIntegerArray.get(0));
}
运行结果

0
0
0
0
0

0 1122
1122 1123

6. AtomicIntegerFieldUpdater

原理:原子性地更新对象的volatile字段,无需使用重量级的锁机制,它通过基于反射的API实现了细粒度的并发控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
class BankAccount//资源类
{
String bankName = "CCB";

//更新的对象属性必须使用 public volatile 修饰符。
public volatile int money = 0;//钱数

// 为什么add方法不能保证安全?
public void add() {
money++;
}

//因为对象的属性修改类型原子类都是抽象类,所以每次使用都必须
// 使用静态方法newUpdater()创建一个更新器,并且需要设置想要更新的类和属性。

AtomicIntegerFieldUpdater<BankAccount> fieldUpdater =
AtomicIntegerFieldUpdater.newUpdater(BankAccount.class,"money");

//不加synchronized,保证高性能原子性,局部微创小手术
public void transMoney(BankAccount bankAccount) {
fieldUpdater.getAndIncrement(bankAccount);
}

}

/**
* 需求:
* 10个线程,
* 每个线程转账1000,
* 不使用synchronized,尝试使用AtomicIntegerFieldUpdater来实现。
*/
public class AtomicIntegerFieldUpdaterDemo
{
public static void main(String[] args) throws InterruptedException {
BankAccount bankAccount = new BankAccount();
CountDownLatch countDownLatch = new CountDownLatch(10);

for (int i = 1; i <=10; i++) {
new Thread(() -> {
try {
for (int j = 1; j <=1000; j++) {
//bankAccount.add();
bankAccount.transMoney(bankAccount);
}
} finally {
countDownLatch.countDown();
}
},String.valueOf(i)).start();
}

countDownLatch.await();

System.out.println(Thread.currentThread().getName()+"\t"+"result: "+bankAccount.money);
}
}

运行结果

main result: 10000

7. AtomicMarkableReference

解决ABA问题,如果变量已经被更新,则isMarked返回true

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
static AtomicMarkableReference markableReference = new AtomicMarkableReference(100,false);
{
new Thread(() -> {
boolean marked = markableReference.isMarked();
System.out.println(Thread.currentThread().getName()+"\t"+"默认标识:"+marked);
//暂停1秒钟线程,等待后面的T2线程和我拿到一样的模式flag标识,都是false
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
boolean a = markableReference.compareAndSet(100,1000,marked,!marked);
System.out.println(Thread.currentThread().getName()+"\t"+"t1线程CASresult: "+a);
System.out.println(Thread.currentThread().getName()+"\t"+markableReference.isMarked());
System.out.println(Thread.currentThread().getName()+"\t"+markableReference.getReference());
},"t1").start();

new Thread(() -> {
boolean marked = markableReference.isMarked();
System.out.println(Thread.currentThread().getName()+"\t"+"默认标识:"+marked);

try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
boolean b = markableReference.compareAndSet(100, 2000, marked, !marked);
System.out.println(Thread.currentThread().getName()+"\t"+"t2线程CASresult: "+b);
System.out.println(Thread.currentThread().getName()+"\t"+markableReference.isMarked());
System.out.println(Thread.currentThread().getName()+"\t"+markableReference.getReference());
},"t2").start();
}
运行结果

t1 默认标识:false
t2 默认标识:false
t1 t1线程CASresult: true
t1 true
t1 1000
t2 t2线程CASresult: false
t2 true
t2 1000

8. AtomicStampedReference

AtomicMarkableReference一样,解决ABA问题,这里使用的是version版本号来区分数据是否发生了改变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@NoArgsConstructor
@AllArgsConstructor
@Data
class Book
{
private int id;
private String bookName;
}

/**
* @auther hsf
* @create 2022-02-24 17:34
*/
public class AtomicStampedDemo
{
public static void main(String[] args)
{
Book javaBook = new Book(1,"javaBook");

AtomicStampedReference<Book> stampedReference = new AtomicStampedReference<>(javaBook,1);

System.out.println(stampedReference.getReference()+"\t"+stampedReference.getStamp());

Book mysqlBook = new Book(2,"mysqlBook");

boolean b;
b = stampedReference.compareAndSet(javaBook, mysqlBook, stampedReference.getStamp(), stampedReference.getStamp() + 1);

System.out.println(b+"\t"+stampedReference.getReference()+"\t"+stampedReference.getStamp());


b = stampedReference.compareAndSet(mysqlBook, javaBook, stampedReference.getStamp(), stampedReference.getStamp() + 1);

System.out.println(b+"\t"+stampedReference.getReference()+"\t"+stampedReference.getStamp());

}
}

运行结果

Book(id=1, bookName=javaBook) 1
true Book(id=2, bookName=mysqlBook) 2
true Book(id=1, bookName=javaBook) 3

9. AtomicReferenceFieldUpdater

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//资源类
class MyVar {
public volatile Boolean isInit = Boolean.FALSE;

AtomicReferenceFieldUpdater<MyVar,Boolean> referenceFieldUpdater =
AtomicReferenceFieldUpdater.newUpdater(MyVar.class,Boolean.class,"isInit");

public void init(MyVar myVar) {
if (referenceFieldUpdater.compareAndSet(myVar,Boolean.FALSE,Boolean.TRUE)) {
System.out.println(Thread.currentThread().getName()+"\t"+"----- start init,need 2 seconds");
//暂停几秒钟线程
try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println(Thread.currentThread().getName()+"\t"+"----- over init");
} else {
System.out.println(Thread.currentThread().getName()+"\t"+"----- 已经有线程在进行初始化工作。。。。。");
}
}
}


/**
* 需求:
* 多线程并发调用一个类的初始化方法,如果未被初始化过,将执行初始化工作,
* 要求只能被初始化一次,只有一个线程操作成功
*/
public class AtomicReferenceFieldUpdaterDemo {
public static void main(String[] args) {
MyVar myVar = new MyVar();

for (int i = 1; i <=5; i++) {
new Thread(() -> {
myVar.init(myVar);
},String.valueOf(i)).start();
}
}
}

运行结果

2 —– 已经有线程在进行初始化工作。。。。。
1 —– start init,need 2 seconds
3 —– 已经有线程在进行初始化工作。。。。。
4 —– 已经有线程在进行初始化工作。。。。。
5 —– 已经有线程在进行初始化工作。。。。。
1 —– over init


本站由 卡卡龙 使用 Stellar 1.29.1主题创建

本站访问量 次. 本文阅读量 次.