多线程下使用wait和notify为什么写在while里面,而不
2023-10-29 本文已影响0人
深夜小码农
多线程下使用wait和notify为什么写在while里面,而不是if?
1、在线程下,wait状态会进入waitset队列等待, 没有抢占到锁的线程synchronized,会进入到entryset队列 等待
2、假设有生产者和消费者。同时有多个生产者生产,多个消费者消费
3、如果是if状态,有一个生产者wait住,一个消费者wait住,另一个消费者已消费完,会notifyAll所有线程,则消费者先抢到锁,那么它会直接进行后续操作,可能这个后续操作的条件并不满足于if条件判断的条件。
4、如果使用while则不会出现这种情况,因为会进行while条件循环判断,满足则执行后续操作
示例代码
/**
* @Description
* @Author jackzhang
*/
public class Thread03{
private Buffer mbuffer = new Buffer();
// private List<Object> list = new ArrayList<>();
public void product(){
synchronized (this) {
if (mbuffer.isFull()){
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
mbuffer.add();
notifyAll();
}
}
public void consumer(){
synchronized (this) {
if (mbuffer.isEmpty()){
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
mbuffer.remove();
notifyAll();
}
}
private class Buffer {
private static final int MAX_CAPACITY = 1;
private List innerList = new ArrayList<>(MAX_CAPACITY);
void add() {
if (isFull()) {
throw new IndexOutOfBoundsException();
} else {
innerList.add(new Object());
}
System.out.println(Thread.currentThread().toString() + " add");
}
void remove() {
if (isEmpty()) {
throw new IndexOutOfBoundsException();
} else {
innerList.remove(MAX_CAPACITY - 1);
}
System.out.println(Thread.currentThread().toString() + " remove");
}
boolean isEmpty() {
return innerList.isEmpty();
}
boolean isFull() {
return innerList.size() == MAX_CAPACITY;
}
}
public static void main(String[] args) {
Thread03 thread03 = new Thread03();
Runnable product = new Runnable() {
int count = 4;
@Override
public void run() {
while (count-- > 0) {
thread03.product();
}
}
};
Runnable consumer = new Runnable(){
@Override
public void run() {
int count = 4;
while (count-- >0){
thread03.consumer();
} }
};
for (int i = 0; i < 2; i++) {
new Thread(product).start();
}
for (int i = 0; i < 2; i++) {
new Thread(consumer).start();
}
}
}