为什么要用wait和notify?
线程锁死后用wait()、notify()、notifyall(),来实现线程同步时的方法调用问题,唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。代码块可以调用wait()方法来将自身的操作挂起,直到同一个对象上的其他同步方法或同步代码块以某种方式将其改变,并调用notify()方法来通知此代码块改变已经完成。
对一个数字当数字大于0时让他自减,小于100时让他自加,在两个线程中进行。例子如下:
消费者:
package com.test.runable;
public class Consumer implements Runnable {
private ShareValue value;
//得到value
public Consumer(ShareValue value) {
this.value = value;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
try {
value.minus();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
生产者:
package com.test.runable;
public class Producer implements Runnable {
private ShareValue value;
public Producer(ShareValue value) {
this.value = value;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
try {
value.plus();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
ShareValue:
package com.test.runable;
public class ShareValue {
private int count;
public ShareValue(int count) {
//更新count
this.count = count;
}
public synchronized void plus() throws InterruptedException {
/*
* 如果count小于100,则count自加,并且执行被阻塞的线程,即notifyall用来执行被阻塞的所有线程*/
if (count <= 100) {
++count;
System.out.println("Producer:" + count);
this.notifyAll();//执行其他被阻塞的线程
} else {
System.out.println("值超过100,停止增加!");
this.wait();//进入wait状态,执行其他线程
}
}
public synchronized void minus() throws InterruptedException {
if (count > 0) {
--count;
System.err.println("Consumer:" + count);
this.notifyAll();
} else {
System.out.println("值小或等于0,停止减少!");
this.wait();
}
}
}
main函数:
package com.test.runable;
public class TestPC {
public static void main(String[] args) {
ShareValue value = new ShareValue(0);
// Runnable pr = new Producer(value);
// Runnable cr = new Consumer(value);
// new Thread(pr).start();
// new Thread(cr).start();
/*
* 起两个线程分别用来启动plus和minus*/
Thread thread1 = new Thread(new Producer(value));
Thread thread2 = new Thread(new Consumer(value));
thread1.start();
thread2.start();
}
}