1. 变量递增试验
1 static /*volatile*/ int shared=0;//volatile也无法保证++操作的原子性
2 static synchronized int incrShared(){//不加synchronized的话,shared最终结果值小于预期
3 return ++shared;
4 }
5 public static void testIncrShared(String[] args) throws InterruptedException {
6 shared=0;
7 Thread[] thrds = new Thread[20];
8 for(int j=0;j<thrds.length;j++){
9 thrds[j] = new Thread(new Runnable() {
10 @Override
11 public void run() {
12 for(int k=0;k<1000;k++){
13 System.out.println(incrShared());
14 }
15 }
16 });
17 }
18 for(int j=0;j<thrds.length;j++){
19 thrds[j].start();
20 }
21 for(int j=0;j<thrds.length;j++){
22 thrds[j].join();
23 }
24 System.out.println(shared);
25 }
2. volatile试验
1 static /*volatile*/ int a0,a1;//这里加volatile的话,可以避免r0==r1==0的结果
2 static /*volatile*/ int r0,r1;//这里即使加volatile,也无法避免r0==r1==0的结果
3 public static void testVolatile(String[] args) throws InterruptedException {
4 int[] a=new int[2];
5 int[] r=new int[2];
6 final int SLEEP=10;
7 final Object lock=new Object();
8 Runnable run1=new Runnable() {
9 @Override
10 public void run() {
11 try {
12 Thread.sleep(SLEEP);
13 } catch (InterruptedException e) {
14 e.printStackTrace();
15 }
16 //synchronized (lock) {//加锁也可以建立happens-before关系,避免r0==r1==0的结果
17 a0=1;
18 //}
19 r1=a1;
20 }
21 };
22 Runnable run2=new Runnable() {
23 @Override
24 public void run() {
25 try {
26 Thread.sleep(SLEEP);
27 } catch (InterruptedException e) {
28 e.printStackTrace();
29 }
30 //synchronized (lock) {
31 a1=1;
32 //}
33 r0=a0;
34 }
35 };
36 Thread thrd1;
37 Thread thrd2;
38
39 int i;
40 int[][] acnt=new int[2][2];
41 int[][] rcnt=new int[2][2];
42 for(i=0;i<10000;i++){
43 a0=a1=0;
44 r0=r1=0;
45 thrd1 = new Thread(run1);
46 thrd2 = new Thread(run2);
47
48 thrd1.start();
49 thrd2.start();
50
51 thrd1.join();
52 thrd2.join();
53
54 a[0]=a0;
55 a[1]=a1;
56 r[0]=r0;
57 r[1]=r1;
58 System.out.println(i);
59 System.out.println(Arrays.toString(a));
60 System.out.println(Arrays.toString(r));
61 acnt[a[0]][a[1]]++;
62 rcnt[r[0]][r[1]]++;
63 }
64 System.out.println(Arrays.deepToString(acnt));
65 System.out.println(Arrays.deepToString(rcnt));
66 }
3. volatile试验2
1 static boolean shouldStop=false;
2 public static void testVolatile2(String[] args) throws InterruptedException {
3 shouldStop=false;
4 Runnable run1=new Runnable() {
5 @Override
6 public void run() {
7 int i=0;
8 while (!shouldStop) {//无法读取到线程2修改后的shouldStop值,导致无限循环
9 i++;
10 //System.out.println(i);//如果调用其他函数的话,就又可以读取到shouldStop的最新值了
11 }
12 }
13 };
14 Runnable run2=new Runnable() {
15 @Override
16 public void run() {
17 try {
18 Thread.sleep(10);
19 } catch (InterruptedException e) {
20 e.printStackTrace();
21 }
22 shouldStop=true;
23 }
24 };
25 Thread thrd1;
26 Thread thrd2;
27
28 int i;
29 int[][] acnt=new int[2][2];
30 int[][] rcnt=new int[2][2];
31 for(i=0;i<100;i++){
32 thrd1 = new Thread(run1);
33 thrd2 = new Thread(run2);
34
35 thrd1.start();
36 thrd2.start();
37
38 thrd2.join();
39 System.out.println(i);
40 System.out.println(shouldStop);
41 thrd1.join();
42
43 }
44 }