线程通信
线程的作用
1.将任务分隔到独立的逻辑单元中进行处理
2.消除了轮询机制,通过轮询检查某些情况是否成立
3.java是隐式监视器,每个实例都具有线程相关方法
4.通过以上几点减少了cpu的浪费,提高了cpu的生产效率
为避免轮询java 提供了wait notify notifyAll 方法进行线程通讯从而避免数据提供者和消费者之间的轮询对cpu消耗
下面先模拟两个线程,一个是生产者,一个是消费者
实例Q
class Q{
int n;
synchronized void put(int n){
this.n = n;
System.out.println("put\t" + n);
}
synchronized void get(){
System.out.println("get\t" + n);
}
}
生产者
class Producer implements Runnable{
Thread t;
Q q;
public Producer(Q q){
this.q = q;
t = new Thread(this,"producer");
t.start();
}
@Override
public void run() {
int i = 0;
int index =0;
while(index < 20){
index++;
q.put(i++);
}
}
}
消费者
class Consumer implements Runnable{
Q q;
Thread t;
public Consumer(Q q){
this.q = q;
t = new Thread(this,"consumer");
t.start();
}
@Override
public void run() {
int index = 0;
while(index < 20){
index++;
q.get();
}
}
}
测试及结果
public static void main(String[] args) {
Q q = new Q();
Producer p = new Producer(q);
Consumer c = new Consumer(q);
}
多进行测试结果不同,但是都反映了一个问题,两个线程之间并没有按照预想,一个生产,一个消费,而是自己干自己的,并关心数据的正确性
put 0
put 1
put 2
put 3
put 4
get 4
get 4
get 4
get 4
get 4
使用wait notify
修改Q类的put 和get的代码
.......
boolean setFlag = false;
synchronized void put(int n){
while(setFlag){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.n = n;
setFlag = true;
notify();
System.out.println("put\t" + n);
}
synchronized void get(){
while(!setFlag){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
setFlag = false;
System.out.println("get\t" + n);
}
...............
输出结果
put 0
get 0
put 1
get 1
put 2
get 2
put 3
get 3
put 4
get 4
死锁