第一章 并发编程的挑战

并发会有上下文切换,所以一定规模下不一定比串行快,来看一个比较:

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
public class ConcurrencyTest {
private final int count = 2000000000;

public void concurrencyFor() throws InterruptedException {
long start = System.currentTimeMillis();
Thread thread = new Thread(new Runnable() {
public void run() {
for (int i = 0; i < count; i++) ;
}
});
thread.start();
for (int i = 0; i < count; i++) ;
thread.join();
long finish = System.currentTimeMillis();
System.out.print("concurrency time=");
System.out.println(finish - start);
}

public void serialFor() {
long start = System.currentTimeMillis();
for (int i = 0; i < count; i++) ;
for (int i = 0; i < count; i++) ;
long finish = System.currentTimeMillis();
System.out.print("serial time=");
System.out.println(finish - start);
}

public static void main(String[] args) throws InterruptedException {
ConcurrencyTest test = new ConcurrencyTest();
test.concurrencyFor();
test.serialFor();
}
}

记得有个面试官问我一个CPU的话有没有必要写并发编程,我回答没必要。凸显了我的无知,我忘记了指令级别的优化,唉。

测试上下文切换
时长:Lmbench3
次数:vmstat
查看线程信息: jstack

查看死锁

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
package chapter01;

/**
* Created by hero on 17-3-11.
*/
public class DeadLock {
private Object a = new Object();
private Object b = new Object();

public static void main(String[] args) {
new DeadLock().fun();
}

private void fun() {
Thread t1 = new Thread(new Runnable() {
public void run() {
synchronized (a) {
for (int i = 0; i < 100000000; i++) ;
synchronized (b) {
System.out.println("a b");
}
}
}
});

Thread t2 = new Thread(new Runnable() {
public void run() {
synchronized (b) {
for (int i = 0; i < 100000000; i++) ;
synchronized (a) {
System.out.println("b a");
}
}
}
});

t1.start();
t2.start();
}
}
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
 $: pgrep java

$: jstack pid > ~/temp/log
得到的结果如下
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x00007fed60004e28 (object 0x000000076d0951b0, a java.lang.Object),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x00007fed600062c8 (object 0x000000076d0951c0, a java.lang.Object),
which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
at chapter01.DeadLock$2.run(DeadLock.java:31)
- waiting to lock <0x000000076d0951b0> (a java.lang.Object)
- locked <0x000000076d0951c0> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)
"Thread-0":
at chapter01.DeadLock$1.run(DeadLock.java:20)
- waiting to lock <0x000000076d0951c0> (a java.lang.Object)
- locked <0x000000076d0951b0> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.

总结:避免死锁,减少上下文切换,根据资源限制(软、硬件)来控制并发。