Skip to content

Commit 37be8be

Browse files
Thread Security
1 parent 9afac2e commit 37be8be

File tree

10 files changed

+482
-1
lines changed

10 files changed

+482
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ Java并发编程
1010
Thread和Object中的重要方法
1111
线程的属性
1212
未捕获异常的处理
13+
线程安全问题
1314
ThreadPool
1415
ThreadLocal
15-
16+
1617

1718
##
1819
乐观与悲观锁
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package threadsecurity;
2+
3+
/**
4+
* 演示死锁 发布逸出
5+
*
6+
* @Author: zzStar
7+
* @Date: 10-19-2020 11:46
8+
*/
9+
public class DeadLock implements Runnable {
10+
11+
int flag = 1;
12+
static Object object1 = new Object();
13+
static Object object2 = new Object();
14+
15+
public static void main(String[] args) {
16+
DeadLock deadLock1 = new DeadLock();
17+
DeadLock deadLock2 = new DeadLock();
18+
deadLock1.flag = 1;
19+
deadLock2.flag = 0;
20+
new Thread(deadLock1).start();
21+
new Thread(deadLock2).start();
22+
}
23+
24+
@Override
25+
public void run() {
26+
System.out.println("flag = " + flag);
27+
if (flag == 1) {
28+
synchronized (object1) {
29+
try {
30+
Thread.sleep(500);
31+
} catch (InterruptedException e) {
32+
e.printStackTrace();
33+
}
34+
synchronized (object2) {
35+
System.out.println("1");
36+
}
37+
}
38+
}
39+
40+
if (flag == 0) {
41+
synchronized (object2) {
42+
try {
43+
Thread.sleep(500);
44+
} catch (InterruptedException e) {
45+
e.printStackTrace();
46+
}
47+
synchronized (object1) {
48+
System.out.println("1");
49+
}
50+
}
51+
}
52+
53+
}
54+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package threadsecurity;
2+
3+
/**
4+
* 工厂模式修复初始化问题
5+
*
6+
* @Author: zzStar
7+
* @Date: 10-19-2020 13:01
8+
*/
9+
public class FactoryPattern {
10+
11+
int count;
12+
private EventListener listener;
13+
14+
// 保护起来
15+
private FactoryPattern(MySource mySource) {
16+
17+
listener = e -> System.out.println("得到的数字是" + count);
18+
19+
for (int i = 0; i < 1000; i++) {
20+
System.out.print(i);
21+
}
22+
count = 100;
23+
}
24+
25+
// 工厂方法
26+
public static FactoryPattern getInstance(MySource mySource) {
27+
FactoryPattern factoryPattern = new FactoryPattern(mySource);
28+
// 完成所有准备工作再注册
29+
mySource.registerListener(factoryPattern.listener);
30+
return factoryPattern;
31+
}
32+
33+
public static void main(String[] args) {
34+
MySource mySource = new MySource();
35+
36+
new Thread(() -> {
37+
try {
38+
Thread.sleep(10);
39+
} catch (InterruptedException e) {
40+
e.printStackTrace();
41+
}
42+
mySource.eventCome(new Event() {
43+
});
44+
}).start();
45+
46+
// 初始化
47+
FactoryPattern factoryPattern = new FactoryPattern(mySource);
48+
}
49+
50+
static class MySource {
51+
52+
// 注册监听器
53+
private EventListener listener;
54+
55+
void registerListener(EventListener eventListener) {
56+
this.listener = eventListener;
57+
}
58+
59+
void eventCome(Event e) {
60+
if (listener != null) {
61+
listener.onEvent(e);
62+
} else {
63+
System.out.println("还未初始化完毕");
64+
}
65+
}
66+
}
67+
68+
interface EventListener {
69+
void onEvent(Event e);
70+
}
71+
72+
interface Event {
73+
74+
}
75+
76+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package threadsecurity;
2+
3+
import java.util.concurrent.BrokenBarrierException;
4+
import java.util.concurrent.CyclicBarrier;
5+
import java.util.concurrent.atomic.AtomicInteger;
6+
7+
/**
8+
* 1.运行结果出错
9+
* 计数不准确,并且找出具体出错的位置
10+
*
11+
* @Author: zzStar
12+
* @Date: 10-18-2020 19:38
13+
*/
14+
public class MultiThreadError implements Runnable {
15+
16+
int index = 0;
17+
18+
static AtomicInteger realIndex = new AtomicInteger();
19+
static AtomicInteger wrongCount = new AtomicInteger();
20+
21+
// 等待共同出发
22+
static volatile CyclicBarrier cyclicBarrier1 = new CyclicBarrier(2);
23+
static volatile CyclicBarrier cyclicBarrier2 = new CyclicBarrier(2);
24+
25+
final boolean[] marked = new boolean[30000];
26+
27+
static MultiThreadError multiThreadError = new MultiThreadError();
28+
29+
public static void main(String[] args) throws InterruptedException {
30+
Thread thread1 = new Thread(multiThreadError);
31+
Thread thread2 = new Thread(multiThreadError);
32+
thread1.start();
33+
thread2.start();
34+
// 使得主线程等待两个子线程停止
35+
thread1.join();
36+
thread2.join();
37+
System.out.println("表面上运行的结果" + multiThreadError.index);//<20000
38+
System.out.println("真正运行的次数" + realIndex.get());
39+
System.out.println("错误运行的次数" + wrongCount.get());
40+
}
41+
42+
43+
@Override
44+
public void run() {
45+
/*
46+
while (index < 1000) {
47+
index++;
48+
}
49+
*/
50+
marked[0] = true;
51+
52+
for (int i = 0; i < 10000; i++) {
53+
54+
// 两个线程都到await才继续
55+
try {
56+
cyclicBarrier2.reset();
57+
cyclicBarrier1.await();
58+
} catch (InterruptedException | BrokenBarrierException e) {
59+
e.printStackTrace();
60+
}
61+
62+
index++;
63+
64+
// 都++后就才继续
65+
try {
66+
cyclicBarrier1.reset();
67+
cyclicBarrier2.await();
68+
} catch (InterruptedException | BrokenBarrierException e) {
69+
e.printStackTrace();
70+
}
71+
72+
// 原子操作下准确的值
73+
realIndex.incrementAndGet();
74+
75+
// 这里需要同步,确保不被打断,并且保证可见性
76+
synchronized (multiThreadError) {
77+
78+
// 前一位也必须是true
79+
if (marked[index] && marked[index - 1]) {
80+
System.out.println("发生错误已被标记" + index);
81+
// 发生的错误数也增加
82+
wrongCount.incrementAndGet();
83+
}
84+
85+
// 存进marked,标记
86+
marked[index] = true;
87+
}
88+
}
89+
}
90+
91+
92+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package threadsecurity;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
/**
7+
* 构造函数中新建线程
8+
*
9+
* @Author: zzStar
10+
* @Date: 10-19-2020 12:48
11+
*/
12+
public class NewThreadConstructor {
13+
14+
private Map<String, String> states;
15+
16+
17+
// 构造函数中新建线程
18+
public NewThreadConstructor() {
19+
new Thread(() -> {
20+
states = new HashMap<>();
21+
states.put("1", "a");
22+
states.put("2", "b");
23+
states.put("3", "c");
24+
}).start();
25+
}
26+
27+
public Map<String, String> getStates() {
28+
return states;
29+
}
30+
31+
public static void main(String[] args) throws InterruptedException {
32+
NewThreadConstructor newThreadConstructor = new NewThreadConstructor();
33+
// java.lang.NullPointerException
34+
// 初始化的工作在另外一个线程还没执行完毕
35+
// 时间不同,结果不同
36+
Thread.sleep(1000);
37+
System.out.println(newThreadConstructor.getStates().get("1"));
38+
39+
}
40+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package threadsecurity;
2+
3+
/**
4+
* 观察者模式
5+
* 利用工厂模式解决问题
6+
*
7+
* @Author: zzStar
8+
* @Date: 10-19-2020 12:23
9+
*/
10+
public class Observer {
11+
12+
int count;
13+
14+
public Observer(MySource mySource) {
15+
16+
// 匿名内部类中持有外部类的引用
17+
mySource.registerListener((Event e) -> {
18+
// 我得到的数字是0
19+
System.out.println("\n我得到的数字是" + count);
20+
});
21+
22+
for (int i = 0; i < 1000; i++) {
23+
System.out.print(i);
24+
}
25+
count = 100;
26+
}
27+
28+
public static void main(String[] args) {
29+
MySource mySource = new MySource();
30+
31+
new Thread(() -> {
32+
try {
33+
Thread.sleep(10);
34+
} catch (InterruptedException e) {
35+
e.printStackTrace();
36+
}
37+
mySource.eventCome(new Event() {
38+
});
39+
}).start();
40+
41+
// 初始化
42+
Observer observer = new Observer(mySource);
43+
}
44+
45+
static class MySource {
46+
47+
// 注册监听器
48+
private EventListener listener;
49+
50+
void registerListener(EventListener eventListener) {
51+
this.listener = eventListener;
52+
}
53+
54+
void eventCome(Event e) {
55+
if (listener != null) {
56+
listener.onEvent(e);
57+
} else {
58+
System.out.println("还未初始化完毕");
59+
}
60+
}
61+
}
62+
63+
interface EventListener {
64+
void onEvent(Event e);
65+
}
66+
67+
interface Event {
68+
69+
}
70+
}
210 KB
Loading
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package threadsecurity;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
/**
7+
* 发布逸出
8+
* 利用副本解决问题
9+
*
10+
* @Author: zzStar
11+
* @Date: 10-19-2020 11:55
12+
*/
13+
public class ReleaseEscape {
14+
15+
// 这里定义为private
16+
private Map<String, String> states;
17+
18+
public ReleaseEscape() {
19+
states = new HashMap<>();
20+
states.put("1", "a");
21+
states.put("2", "b");
22+
states.put("3", "c");
23+
}
24+
25+
public Map<String, String> getStates() {
26+
// 这里把private发布了
27+
return states;
28+
}
29+
30+
public Map<String, String> getStatesImproved() {
31+
return new HashMap<>(states);
32+
}
33+
34+
public static void main(String[] args) {
35+
ReleaseEscape releaseEscape = new ReleaseEscape();
36+
Map<String, String> states = releaseEscape.getStates();
37+
/*
38+
System.out.println(states.get("1"));
39+
// 被篡改
40+
states.remove("1");
41+
// null
42+
System.out.println(states.get("1"));
43+
*/
44+
System.out.println(releaseEscape.getStatesImproved().get("1"));
45+
releaseEscape.getStatesImproved().remove("1");
46+
// Copied
47+
System.out.println(releaseEscape.getStatesImproved().get("1"));
48+
}
49+
}

0 commit comments

Comments
 (0)