package concurrent.Accumulator;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
public class IntegerAccumulator {
private int init;
// 构造时传入输入初始值
public IntegerAccumulator(int init) {
this.init = init;
}
// 对初始值增加 i
public int add(int i) {
this.init += i;
return this.init;
}
// 返回当前的初始值
public int getValue() {
return this.init;
}
private static void slowly() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// 定义累加器,并且将初始值设置为 0
IntegerAccumulator accumulator = new IntegerAccumulator(0);
// 定义三个线程,并且分别启动
IntStream.range(0, 3).forEach(i -> new Thread(() -> {
int inc = 0;
while (true) {
// 首先获得 old value
int oldValue = accumulator.getValue();
// 然后调用 add 方法计算
int result = accumulator.add(inc);
System.out.println(oldValue + "+" + inc + "=" + result);
// 如果不合理,则输出错误的信息
if (inc + oldValue != result) {
System.out.println("ERROR:" + oldValue + "+" + inc + "=" + result);
}
inc++;
slowly();
}
}).start());
}
}
0+0=0
0+0=0
0+0=0
0+1=1
2+1=3
1+1=2
3+2=5
3+2=5
3+2=5
8+3=11
5+3=8
11+3=14
14+4=18
14+4=18
18+4=22
27+5=32
22+5=27
27+5=32
32+6=38
38+6=44
44+6=50
57+7=64
50+7=57
57+7=71
ERROR:57+7=71
79+8=87
71+8=79
87+8=95
95+9=104
95+9=104
95+9=104
124+10=134
104+10=114
104+10=124
ERROR:104+10=124
package concurrent.Accumulator;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
public class IntegerAccumulator1 {
private int init;
// 构造时传入输入初始值
public IntegerAccumulator1(int init) {
this.init = init;
}
// 对初始值增加 i
public int add(int i) {
this.init += i;
return this.init;
}
// 返回当前的初始值
public int getValue() {
return this.init;
}
private static void slowly() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// 定义累加器,并且将初始值设置为 0
IntegerAccumulator1 accumulator = new IntegerAccumulator1(0);
// 定义三个线程,并且分别启动
IntStream.range(0, 3).forEach(i -> new Thread(() -> {
int inc = 0;
while (true) {
int oldValue;
int result;
// 使用 class 实例作为同步锁
synchronized (IntegerAccumulator.class){
// 首先获得 old value
oldValue = accumulator.getValue();
// 然后调用 add 方法计算
result = accumulator.add(inc);
}
System.out.println(oldValue + "+" + inc + "=" + result);
// 如果不合理,则输出错误的信息
if (inc + oldValue != result) {
System.out.println("ERROR:" + oldValue + "+" + inc + "=" + result);
}
inc++;
slowly();
}
}).start());
}
}
0+0=0
0+0=0
0+0=0
1+1=2
0+1=1
2+1=3
3+2=5
5+2=7
7+2=9
12+3=15
9+3=12
15+3=18
18+4=22
26+4=30
22+4=26
30+5=35
35+5=40
40+5=45
57+6=63
45+6=51
51+6=57
63+7=70
77+7=84
70+7=77
84+8=92
100+8=108
92+8=100
这里将数据同步的控制放在了线程的逻辑执行单元中,而在 IntegerAccumulator1 中未增加任何同步的控制,如果单纯对 getValue 方法和 add 方法增加同步控制,虽然保证了单个方法的原子性,但是两个原子类型的操作在一起未必就是原子性的,因此在线程的逻辑执行单元中增加同步控制是最为合理的。
package concurrent.Accumulator;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
public final class IntegerAccumulator2 {
private int init;
// 构造时传入输入初始值
public IntegerAccumulator2(int init) {
this.init = init;
}
public IntegerAccumulator2(IntegerAccumulator2 accumulator2, int init) {
this.init = accumulator2.getValue() + init;
}
// 对初始值增加 i
public IntegerAccumulator2 add(int i) {
return new IntegerAccumulator2(this, i);
}
// 返回当前的初始值
public int getValue() {
return this.init;
}
private static void slowly() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// 定义累加器,并且将初始值设置为 0
IntegerAccumulator2 accumulator = new IntegerAccumulator2(0);
// 定义三个线程,并且分别启动
IntStream.range(0, 3).forEach(i -> new Thread(() -> {
int inc = 0;
while (true) {
// 首先获得 old value
int oldValue = accumulator.getValue();
// 然后调用 add 方法计算
int result = accumulator.add(inc).getValue();
System.out.println(oldValue + "+" + inc + "=" + result);
// 如果不合理,则输出错误的信息
if (inc + oldValue != result) {
System.out.println("ERROR:" + oldValue + "+" + inc + "=" + result);
}
inc++;
slowly();
}
}).start());
}
}
0+0=0
0+0=0
0+0=0
0+1=1
0+1=1
0+1=1
0+2=2
0+2=2
0+2=2
0+3=3
0+3=3
0+3=3
0+4=4
0+4=4
0+4=4
0+5=5
0+5=5
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/chengqiuming/article/details/124214840
内容来源于网络,如有侵权,请联系作者删除!