Skip to content

Commit 868604a

Browse files
committed
🔖 原子操作类(Atomic)示例
1 parent 42e90b7 commit 868604a

5 files changed

Lines changed: 266 additions & 0 deletions

File tree

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package io.github.dunwu.javase.concurrent.atomic;
2+
3+
import java.util.concurrent.atomic.AtomicIntegerArray;
4+
5+
/**
6+
* @author Zhang Peng
7+
* @date 2018/5/24
8+
*/
9+
public class AtomicIntegerArrayDemo {
10+
11+
private static AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(10);
12+
13+
public static void main(final String[] arguments) throws InterruptedException {
14+
15+
for (int i = 0; i < atomicIntegerArray.length(); i++) {
16+
atomicIntegerArray.set(i, i);
17+
}
18+
19+
Thread t1 = new Thread(new Increment());
20+
Thread t2 = new Thread(new Compare());
21+
t1.start();
22+
t2.start();
23+
24+
t1.join();
25+
t2.join();
26+
27+
System.out.println("Final Values: ");
28+
29+
for (int i = 0; i < atomicIntegerArray.length(); i++) {
30+
System.out.print(atomicIntegerArray.get(i) + " ");
31+
}
32+
}
33+
34+
static class Increment implements Runnable {
35+
36+
public void run() {
37+
38+
for (int i = 0; i < atomicIntegerArray.length(); i++) {
39+
int add = atomicIntegerArray.incrementAndGet(i);
40+
System.out.println(Thread.currentThread().getName() + ", index " + i + ", value: " + add);
41+
42+
}
43+
}
44+
}
45+
46+
static class Compare implements Runnable {
47+
48+
public void run() {
49+
50+
for (int i = 0; i < atomicIntegerArray.length(); i++) {
51+
boolean swapped = atomicIntegerArray.compareAndSet(i, 2, 3);
52+
53+
if (swapped) {
54+
System.out.println(Thread.currentThread().getName() + ", index " + i + ", value: 3");
55+
}
56+
}
57+
}
58+
}
59+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package io.github.dunwu.javase.concurrent.atomic;
2+
3+
import java.util.concurrent.ExecutorService;
4+
import java.util.concurrent.Executors;
5+
import java.util.concurrent.TimeUnit;
6+
import java.util.concurrent.atomic.AtomicInteger;
7+
8+
/**
9+
* @author Zhang Peng
10+
* @date 2018/5/24
11+
*/
12+
public class AtomicIntegerDemo {
13+
14+
public static void main(String[] args) throws InterruptedException {
15+
ExecutorService executorService = Executors.newFixedThreadPool(5);
16+
AtomicInteger count = new AtomicInteger(0);
17+
for (int i = 0; i < 1000; i++) {
18+
executorService.submit((Runnable) () -> {
19+
System.out.println(Thread.currentThread().getName() + " count=" + count.get());
20+
count.incrementAndGet();
21+
});
22+
}
23+
24+
executorService.shutdown();
25+
executorService.awaitTermination(30, TimeUnit.SECONDS);
26+
System.out.println("Final Count is : " + count.get());
27+
}
28+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package io.github.dunwu.javase.concurrent.atomic;
2+
3+
import java.util.concurrent.ExecutorService;
4+
import java.util.concurrent.Executors;
5+
import java.util.concurrent.TimeUnit;
6+
import java.util.concurrent.atomic.AtomicMarkableReference;
7+
8+
/**
9+
* @author Zhang Peng
10+
* @date 2018/5/24
11+
*/
12+
public class AtomicMarkableReferenceDemo {
13+
14+
private final static String INIT_REF = "abc";
15+
16+
public static void main(String[] args) throws InterruptedException {
17+
18+
AtomicMarkableReference<String> amr = new AtomicMarkableReference<>("abc", false);
19+
20+
ExecutorService executorService = Executors.newFixedThreadPool(100);
21+
for (int i = 0; i < 100; i++) {
22+
executorService.submit(() -> {
23+
try {
24+
Thread.sleep(Math.abs((int) (Math.random() * 100)));
25+
} catch (InterruptedException e) {
26+
e.printStackTrace();
27+
}
28+
29+
if (amr.compareAndSet(INIT_REF, Thread.currentThread().getName(), amr.isMarked(), !amr.isMarked())) {
30+
System.out.println(Thread.currentThread().getName() + " 修改了对象!");
31+
System.out.println("新的对象为:" + amr.getReference());
32+
}
33+
});
34+
}
35+
36+
executorService.shutdown();
37+
executorService.awaitTermination(60, TimeUnit.SECONDS);
38+
}
39+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package io.github.dunwu.javase.concurrent.atomic;
2+
3+
import java.util.concurrent.atomic.AtomicReference;
4+
5+
/**
6+
* @author Zhang Peng
7+
* @date 2018/5/24
8+
*/
9+
public class AtomicReferenceDemo {
10+
11+
private static String message;
12+
private static Person person;
13+
private static AtomicReference<String> aRmessage;
14+
private static AtomicReference<Person> aRperson;
15+
16+
public static void main(String[] args) throws InterruptedException {
17+
Thread t1 = new Thread(new MyRun1());
18+
Thread t2 = new Thread(new MyRun2());
19+
message = "hello";
20+
person = new Person("Phillip", 23);
21+
aRmessage = new AtomicReference<String>(message);
22+
aRperson = new AtomicReference<Person>(person);
23+
System.out.println("Message is: " + message
24+
+ "\nPerson is " + person.toString());
25+
System.out.println("Atomic Reference of Message is: " + aRmessage.get()
26+
+ "\nAtomic Reference of Person is " + aRperson.get().toString());
27+
t1.start();
28+
t2.start();
29+
t1.join();
30+
t2.join();
31+
System.out.println("\nNow Message is: " + message
32+
+ "\nPerson is " + person.toString());
33+
System.out.println("Atomic Reference of Message is: " + aRmessage.get()
34+
+ "\nAtomic Reference of Person is " + aRperson.get().toString());
35+
}
36+
37+
static class MyRun1 implements Runnable {
38+
39+
public void run() {
40+
aRmessage.compareAndSet(message, "Thread 1");
41+
message = message.concat("-Thread 1!");
42+
person.setAge(person.getAge() + 1);
43+
person.setName("Thread 1");
44+
aRperson.getAndSet(new Person("Thread 1", 1));
45+
System.out.println("\n" + Thread.currentThread().getName() + " Values "
46+
+ message + " - " + person.toString());
47+
System.out.println("\n" + Thread.currentThread().getName() + " Atomic References "
48+
+ message + " - " + person.toString());
49+
}
50+
}
51+
52+
static class MyRun2 implements Runnable {
53+
54+
public void run() {
55+
message = message.concat("-Thread 2");
56+
person.setAge(person.getAge() + 2);
57+
person.setName("Thread 2");
58+
aRmessage.lazySet("Thread 2");
59+
aRperson.set(new Person("Thread 2", 2));
60+
System.out.println("\n" + Thread.currentThread().getName() + " Values: "
61+
+ message + " - " + person.toString());
62+
System.out.println("\n" + Thread.currentThread().getName() + " Atomic References: "
63+
+ aRmessage.get() + " - " + aRperson.get().toString());
64+
}
65+
}
66+
67+
static class Person {
68+
69+
private String name;
70+
private int age;
71+
72+
Person(String name, int age) {
73+
this.name = name;
74+
this.age = age;
75+
}
76+
77+
public String getName() {
78+
return name;
79+
}
80+
81+
public void setName(String name) {
82+
this.name = name;
83+
}
84+
85+
int getAge() {
86+
return age;
87+
}
88+
89+
void setAge(int age) {
90+
this.age = age;
91+
}
92+
93+
@Override
94+
public String toString() {
95+
return "[name " + this.name + ", age " + this.age + "]";
96+
}
97+
}
98+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package io.github.dunwu.javase.concurrent.atomic;
2+
3+
import java.util.concurrent.ExecutorService;
4+
import java.util.concurrent.Executors;
5+
import java.util.concurrent.TimeUnit;
6+
import java.util.concurrent.atomic.AtomicStampedReference;
7+
8+
/**
9+
* AtomicStampedReference 可以解决 CAS 中的 ABA 问题
10+
* @author Zhang Peng
11+
* @date 2018/5/24
12+
*/
13+
public class AtomicStampedReferenceDemo {
14+
15+
private final static String INIT_REF = "abc";
16+
17+
public static void main(String[] args) throws InterruptedException {
18+
19+
AtomicStampedReference<String> asr = new AtomicStampedReference<>(INIT_REF, 0);
20+
System.out.println("初始对象为:" + asr.getReference());
21+
final int stamp = asr.getStamp();
22+
23+
ExecutorService executorService = Executors.newFixedThreadPool(100);
24+
for (int i = 0; i < 100; i++) {
25+
executorService.submit(() -> {
26+
try {
27+
Thread.sleep(Math.abs((int) (Math.random() * 100)));
28+
} catch (InterruptedException e) {
29+
e.printStackTrace();
30+
}
31+
32+
if (asr.compareAndSet(INIT_REF, Thread.currentThread().getName(), stamp, stamp + 1)) {
33+
System.out.println(Thread.currentThread().getName() + " 修改了对象!");
34+
System.out.println("新的对象为:" + asr.getReference());
35+
}
36+
});
37+
}
38+
39+
executorService.shutdown();
40+
executorService.awaitTermination(60, TimeUnit.SECONDS);
41+
}
42+
}

0 commit comments

Comments
 (0)