简书链接:android开发巩固java基础notifywait的妙用javaandroid测试以及翻出我之前2015年的有道云笔记供大家参考
文章字数:950,阅读全文大约需要3分钟
经常玩 测试类的都应该知道,android测试测试子线程的时候往往直接结束了,并没有看到日志打印,难道真的没法测试了吗?

其实不然,java的notify wait就可以派上用场啦!
在android test快结束的时候 synchronized锁进行等待即可.

有时候java基础还是很重要的啦,当然咯,很久没玩java 线程同步,可能全还给老师也是可以理解的.

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54

package cn.qssq666.videotest;

/**
* Created by qssq on 2018/4/20 [email protected]
*/
public class WaitTest {

@org.junit.Test
public void waitAndNotify() {


final Object lock = new Object();

new Thread(new Runnable() {
int count = 0;

@Override
public void run() {
while (count < 10) {
try {
Thread.sleep(1000);
System.out.println("current :" + count);
} catch (InterruptedException e) {
e.printStackTrace();
}
count++;

}

System.out.println("我是子线程:" + Thread.currentThread().getName());
System.out.println("调用notify start");
synchronized (lock) {

lock.notify();//必须同步锁包裹才能进行调用 Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
}
System.out.println("调用notify end");

}
}).start();
System.out.println("即将进入线程等待");
synchronized (lock) {

try {
lock.wait();
// lock.wait(1000555);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("收到notify,退出等待");
}
}
}

那么打印的结果打印也应该可以猜到了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
即将进入线程等待
current :0
current :1
current :2
current :3
current :4
current :5
current :6
current :7
current :8
current :9
我是子线程:Thread-0
调用notify start
调用notify end
收到notify,退出等待

随便记录一下要添加的依赖

1
2
3
4
5
6
7
8
dependencies {
androidTestCompile 'com.android.support.test:runner:0.4.1'//android测试
androidTestImplementation 'com.android.support.test:rules:0.4.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:2.2.1'//android测试
compile fileTree(include: ['*.jar'], dir: 'libs')
testImplementation 'junit:junit:4.12' //java测试
}

最后我从有道云中找到了我2015年的笔记说实话我现在看的云里雾里,到底是那时候太菜,还是现在太菜忘记了所有???

线程和进程相关知识点

进程 就是运行的程序 
线程 就是  进程 总的一个执行路径
多线程:一个进程中 有多个进行,多个执行路径可以执行多个任务代码
多线程的好处:
解决1个进程中可以执行多个任务
提高了资源利用率
多线的的坏处:
增加了cpu的负担,
降低了进程中线程的执行概率
容易引发线程安全问题
 用同步锁 容易出现死锁现象
线程的创建方式有2中 

1 继承Thread   重写run方法

new自身 继承了父类Thread的start() 所以直接new自身类().start()就可以启动线程

2 实现Runnable  实现run方法

把Runnable实现类传递给Thread类
new Thread(new 实现Runnable类()).start();
JAVA同步机制:

同步代码块

格式:

1
2
3
4
5
synchronized(锁对象)

{

}
同步代码块注意事项

锁对象可以是任意对象,因为有隐式变量 可当锁

锁对象必须多个线程共享一个对象,要保证唯一

一个线程调用sleep方法 不会释放锁对象

如果当前代码没有存在线程安全问题,千万不要使用同步机制

否则会降低执行效率

同步函数

1、非静态函数的锁对象是this对象,静态函数锁对象是当前函数所属类的class对象   this.getClass 
第二种: 直接填写指定文件 如 Person.Class
第三种:对象.getClass
另外获取自身对象 直接 this就可以
死锁现象
线程和线程之间出现了互相等待对象资源的情况

代码笔记
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
package sernirolock1;

//

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

public class Demo {

 /**

  * @param args

  * 高级   不同线程池 实现 线程通信

  * 本例使用lock 显式锁对象和condition 监视器实现了不同线程池 多线程通信

  * 而用synchronized是无法实现的。

  */

 public static void main(String[] args) {

  Resource r = new Resource();

  Lock l = new ReentrantLock();

  Condition cCondition = l.newCondition();

  Condition pCondition = l.newCondition();

  new Producter("情迁的老婆", r, l, cCondition,pCondition).start();

  new Customer("情迁", r, l, cCondition,pCondition).start();

 }

}

class Resource {

 public String name;

 public int price;

 public boolean flag;// 真为已生产

 public Lock lock;

 public Condition condition;

}

class Producter extends Thread {

 Resource resource;

 Lock lock;

 Condition cCondition;

 Condition pCondition;

 public Producter(Resource resource, Lock lock, Condition cCondition,Condition pCondition) {

  this.resource = resource;

  this.lock = lock;

  this.cCondition = cCondition;

  this.pCondition = pCondition;

 }

 /**

  *

  * @param name

  * @param resource

  *            被共享资源

  * @param lock

  *            锁对象

  */

 public Producter(String name, Resource resource, Lock lock,

    Condition cCondition,Condition pCondition) {

  super(name);

  this.resource = resource;

  this.lock = lock;

  this.cCondition = cCondition;

  this.pCondition = pCondition;

 }

 @Override

 public void run() {

  int i = 0;

  while (true) {

   lock.lock();

   if (!resource.flag) {

    if (i % 2 == 0) {

     resource.name = "自行车";

     resource.price = 300;

    } else {

     resource.name = "摩托车";

     resource.price = 1000;

    }

    System.out.println(this.getName() + "生产了价值" + resource.price

      + "元的" + resource.name);

    resource.flag = true;

    cCondition.signal();//我是生产发送信号给监视器->消费者线程

    i++;

   } else {

    try {

     pCondition.await();//我是生产线程,没人消费我就暂时不生产

    } catch (InterruptedException e) {

     //

     e.printStackTrace();

    }

   }

   lock.unlock();

  }

 }

}

class Customer extends Thread {

 Resource resource;

 Lock lock;

 Condition cCondition;

 Condition pCondition;

 public Customer(Resource resource, Lock lock, Condition cCondition,Condition pCondition) {

  this.resource = resource;

  this.lock = lock;

  this.cCondition = cCondition;

  this.pCondition = pCondition;

 }

 public Customer(String name, Resource resource, Lock lock,

    Condition cCondition,Condition pCondition) {

  super(name);

  this.resource = resource;

  this.lock = lock;

  this.cCondition = cCondition;

  this.pCondition = pCondition;

 }

 @Override

 public void run() {

  while (true) {

   lock.lock();

    if (resource.flag) {

     System.out.println(this.getName() + "消费了价值"

       + resource.price + "元的" + resource.name);

     resource.flag = false;

     pCondition.signal();//我是消费发送信号给监视器->生产者线程

    } else {

     try {

      cCondition.await();//我是消费者线程,我已经消费完毕,我睡了哈

     } catch (InterruptedException e) {

      //

      e.printStackTrace();

     }

    }

    lock.unlock();

  }

 }

}