Skip to content

Commit dab537c

Browse files
committed
并发测试相关代码提交
1 parent 84e8851 commit dab537c

4 files changed

Lines changed: 519 additions & 54 deletions

File tree

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.prd.classloader;
2+
3+
import java.io.*;
4+
5+
public class MyFirstClassLoder extends ClassLoader {
6+
7+
private String name;
8+
9+
private final String classNameExt=".class";
10+
11+
public MyFirstClassLoder(String name) {
12+
// 指定系统类加载器当作该类加载器的父加载器
13+
super();
14+
this.name = name;
15+
}
16+
17+
public MyFirstClassLoder(ClassLoader parent,String name) {
18+
// 显示指定该类加载器的父加载器
19+
super(parent);
20+
this.name = name;
21+
}
22+
23+
private byte[] loadClassData(String name) {
24+
byte[] data=null;
25+
InputStream in = null;
26+
ByteArrayOutputStream bout = null;
27+
try {
28+
System.out.println("调用自定义类加载器");
29+
in = new FileInputStream(new File(name+classNameExt));
30+
int ch=0;
31+
while((ch=in.read())!=-1) {
32+
bout.write(ch);
33+
}
34+
data = bout.toByteArray();
35+
36+
} catch (FileNotFoundException e) {
37+
e.printStackTrace();
38+
} catch (IOException e) {
39+
e.printStackTrace();
40+
} finally {
41+
try {
42+
in.close();
43+
bout.close();
44+
} catch (IOException e) {
45+
e.printStackTrace();
46+
}
47+
}
48+
49+
return data;
50+
}
51+
52+
@Override
53+
protected Class<?> findClass(String name) throws ClassNotFoundException {
54+
byte[] data = loadClassData(name);
55+
return defineClass(name,data,0,data.length);
56+
}
57+
58+
59+
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
60+
MyFirstClassLoder classLoder = new MyFirstClassLoder("test1");
61+
// Class cls= classLoder.loadClass("com.prd.classloader.ClassInitTest1");
62+
Class cls= classLoder.loadClass("com.prd.colletctions.ArrayListText");
63+
Object obj = cls.newInstance();
64+
System.out.println("获得对象实例:"+obj);
65+
System.out.println("对象实例的类加载器"+obj.getClass().getClassLoader());
66+
}
67+
68+
/**
69+
* 尝试加载本项目中其他类
70+
* 结果:自定义类加载器不起作用,实际的类加载是由AppClassLoader完成。
71+
* 因为这些类都在是系统项目中,通过双亲模式最终由MyFirstClassLoder的父类加载完成
72+
*/
73+
private static void testLoadLocalClass() {
74+
75+
}
76+
}

src/main/java/com/prd/concurrent/LockSupportTest.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ public class LockSupportTest {
1111
public static void main(String[] args) {
1212
// testNormalUsed();
1313
// testNormalInterrupte();
14-
testUnBeforPark();
14+
// testUnBeforPark();
15+
16+
testParkJStack();
1517
}
1618

1719
/**
@@ -90,5 +92,22 @@ private static void testUnBeforPark(){
9092
test3.start();
9193
}
9294

95+
/**
96+
* 使用park(thread)可以在jstack等工具中显示阻塞的对象
97+
*/
98+
private static void testParkJStack() {
99+
new Thread(()->{
100+
while(!Thread.currentThread().isInterrupted()) {
101+
System.out.println("park this");
102+
LockSupport.park(Thread.currentThread());
103+
}
104+
}).start();
93105

106+
new Thread(()->{
107+
while(!Thread.currentThread().isInterrupted()) {
108+
System.out.println("park");
109+
LockSupport.park();
110+
}
111+
}).start();
112+
}
94113
}
Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
package com.prd.concurrent;
2+
3+
import java.util.TreeSet;
4+
import java.util.concurrent.TimeUnit;
5+
6+
/**
7+
* 线程停止
8+
*/
9+
public class ThreadStopTest {
10+
11+
public static void main(String[] args) {
12+
// rigthStopThreadNoBlock();
13+
// rigthStopThreadBlock();
14+
// rigthStopThreadBlockEveryLoop();
15+
// catInterrupt();
16+
// theSecondWayToStopThread();
17+
wangStopThreadByVolatile();
18+
}
19+
20+
21+
/**
22+
* 无sleep或wait等阻塞时停止线程,
23+
* 需要在线程内部主动判断中断状态
24+
*/
25+
private static void rigthStopThreadNoBlock() {
26+
Thread test = new Thread(() -> {
27+
int num = 0;
28+
// 影响中断
29+
while (!Thread.currentThread().isInterrupted() &&
30+
num < Integer.MAX_VALUE) {
31+
if (num % 10000 == 0) {
32+
System.out.println(num + "是10000的倍数");
33+
}
34+
num++;
35+
}
36+
System.out.println("线程执行完成");
37+
});
38+
test.start();
39+
try {
40+
TimeUnit.SECONDS.sleep(1);
41+
} catch (InterruptedException e) {
42+
e.printStackTrace();
43+
}
44+
test.interrupt();
45+
}
46+
47+
/**
48+
* 线程在由sleep,wait,join等造成的阻塞情况下,停止线程时
49+
* 阻塞方法会响应interrupt方法,并抛出InterruptedException异常
50+
* 结果:
51+
* 0是100的倍数
52+
* java.lang.InterruptedException: sleep interrupted
53+
* at java.lang.Thread.sleep(Native Method)
54+
* at com.prd.concurrent.ThreadStopTest.lambda$rigthStopThreadBlock$1(ThreadStopTest.java:56)
55+
* at java.lang.Thread.run(Thread.java:748)
56+
*/
57+
private static void rigthStopThreadBlock() {
58+
Runnable run = () -> {
59+
int num = 0;
60+
try {
61+
while (num <= 300
62+
&& !Thread.currentThread().isInterrupted()) {
63+
if (num % 100 == 0) {
64+
System.out.println(num + "是100的倍数");
65+
}
66+
num++;
67+
}
68+
Thread.sleep(1000);
69+
} catch (InterruptedException e) {
70+
e.printStackTrace();
71+
}
72+
};
73+
Thread thread = new Thread(run);
74+
thread.start();
75+
try {
76+
Thread.sleep(500);
77+
} catch (InterruptedException e) {
78+
e.printStackTrace();
79+
}
80+
thread.interrupt();
81+
}
82+
83+
/**
84+
* 在执行过程中,每次循环中都会调用sleep等阻塞线程,停止线程时.
85+
* 这里的Thread.currentThread().isInterrupted() 就显得多余,
86+
* 线程停止是while循环内的sleep响应异常控制的。
87+
* 结果:
88+
* 0是100的倍数
89+
* 100是100的倍数
90+
* 200是100的倍数
91+
* 300是100的倍数
92+
* 400是100的倍数
93+
* java.lang.InterruptedException: sleep interrupted
94+
*/
95+
private static void rigthStopThreadBlockEveryLoop() {
96+
Runnable run = () -> {
97+
int num = 0;
98+
try {
99+
while (num <= 10000) {
100+
if (num % 100 == 0) {
101+
System.out.println(num + "是100的倍数");
102+
}
103+
num++;
104+
Thread.sleep(10);
105+
}
106+
} catch (InterruptedException e) {
107+
e.printStackTrace();
108+
}
109+
};
110+
Thread thread = new Thread(run);
111+
thread.start();
112+
try {
113+
Thread.sleep(5000);
114+
} catch (InterruptedException e) {
115+
e.printStackTrace();
116+
}
117+
thread.interrupt();
118+
}
119+
120+
/**
121+
* 如果while或for的循环中有try/catch,会导致中断失效。
122+
* 结果:
123+
* 400是100的倍数
124+
* java.lang.InterruptedException: sleep interrupted
125+
* at java.lang.Thread.sleep(Native Method)
126+
* at com.prd.concurrent.ThreadStopTest.lambda$catInterrupt$3(ThreadStopTest.java:129)
127+
* at java.lang.Thread.run(Thread.java:748)
128+
* 500是100的倍数
129+
* 600是100的倍数
130+
* <p>
131+
* try/catch会拦截处理掉InterruptedException,并且中断状态判断失效
132+
*/
133+
private static void catInterrupt() {
134+
Runnable run = () -> {
135+
int num = 0;
136+
while (num <= 10000) {
137+
// 这里的判断状态无效
138+
if (num % 100 == 0
139+
&& !Thread.currentThread().isInterrupted()) {
140+
System.out.println(num + "是100的倍数");
141+
}
142+
num++;
143+
try {
144+
Thread.sleep(10);
145+
} catch (InterruptedException e) {
146+
// 抛出异常后,导致中断状态被清除,故而Thread.currentThread().isInterrupted()
147+
//失效
148+
e.printStackTrace();
149+
}
150+
}
151+
};
152+
Thread thread = new Thread(run);
153+
thread.start();
154+
try {
155+
Thread.sleep(5000);
156+
} catch (InterruptedException e) {
157+
e.printStackTrace();
158+
}
159+
thread.interrupt();
160+
}
161+
162+
/**
163+
* 在生成环境中,中断线程最佳实践:catche了InterruptedException之后的优先选择:
164+
* 在方法签名中抛出异常。那么在run()就会强制try/catch。
165+
* 因为在run方法中只能catch,不能再往外抛出任何异常,因为run方法是重写的,在接口中run方法的定义中本来就没有抛出异常。
166+
* 重写方法是不能破坏父类或接口方法的定义的。
167+
*/
168+
private static void theFirstWayToStopThread() {
169+
Runnable runA = () -> {
170+
while (true) {
171+
System.out.println("生产开始");
172+
try {
173+
throwInMethod();
174+
} catch (InterruptedException e) {
175+
// 保存日志,停止程序
176+
System.out.println("保存日志");
177+
e.printStackTrace();
178+
}
179+
}
180+
};
181+
Thread test1 = new Thread(runA);
182+
test1.start();
183+
try {
184+
Thread.sleep(1000);
185+
} catch (InterruptedException e) {
186+
e.printStackTrace();
187+
}
188+
test1.interrupt();
189+
}
190+
191+
/**
192+
* 实际的生成方法
193+
*/
194+
private static void throwInMethod() throws InterruptedException {
195+
Thread.sleep(2000);
196+
}
197+
198+
/**
199+
* 在生产环境中,中断线程最佳实践2:在catch子句中调用Thread.currentThread().interrupt()
200+
* 来恢复设置中断状态,以便于在后续的执行中,依然能否检查到刚才发生了中断。
201+
*/
202+
private static void theSecondWayToStopThread() {
203+
Runnable runA = () -> {
204+
while (true) {
205+
System.out.println("生产开始");
206+
if (Thread.currentThread().isInterrupted()) {
207+
System.out.println("Interrupted 程序运行结束");
208+
break;
209+
}
210+
reInterrupt();
211+
}
212+
};
213+
Thread test1 = new Thread(runA);
214+
test1.start();
215+
try {
216+
Thread.sleep(1000);
217+
} catch (InterruptedException e) {
218+
e.printStackTrace();
219+
}
220+
test1.interrupt();
221+
}
222+
223+
/**
224+
* 实际的生成方法
225+
*/
226+
private static void reInterrupt() {
227+
try {
228+
Thread.sleep(2000);
229+
} catch (InterruptedException e) {
230+
Thread.currentThread().interrupt();
231+
e.printStackTrace();
232+
}
233+
}
234+
235+
private volatile static boolean canceled = false;
236+
237+
/**
238+
* 错误方法:使用volatile变量来控制线程中断.
239+
* 结论:貌似看起来可行。
240+
* 但是如果线程是阻塞状态时,volatile并不会起作用
241+
*/
242+
private static void wangStopThreadByVolatile() {
243+
new Thread(() -> {
244+
int num = 0;
245+
try {
246+
while (num <= 10000 && !canceled) {
247+
if (num%100 == 0) {
248+
System.out.println(num + "是100的倍数");
249+
}
250+
num++;
251+
// 如果sleep时间过长,在阻塞状态时来改变canceled是无效的
252+
// 如果这是wait,则会导致线程长时间阻塞,无法中断了
253+
Thread.sleep(10);
254+
}
255+
} catch (InterruptedException e) {
256+
e.printStackTrace();
257+
}
258+
}).start();
259+
260+
try {
261+
Thread.sleep(5000);
262+
} catch (InterruptedException e) {
263+
e.printStackTrace();
264+
}
265+
canceled = true;
266+
}
267+
}

0 commit comments

Comments
 (0)