package Thread;
/**
*
* // 生产者消费者问题
* @author Muluo
* @create 2021-02-14 19:23
*/
public class CustomerAndProvide {
public static void main(String[] args) {
Data data = new Data();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "a").start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "b").start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "c").start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "d").start();
}
}
class Data{
private int num = 0;
public synchronized void decrement() throws InterruptedException {
if (num != 0) {
this.wait();
}
num++;
System.out.println(Thread.currentThread().getName() + "->" + num);
this.notifyAll();
}
public synchronized void increment() throws InterruptedException {
if (num ==0) {
this.wait();
}
num--;
System.out.println(Thread.currentThread().getName() + "->" + num);
this.notifyAll();
}
}
This code has the problem of false wake-up, so you should replace if with while for multiple judgments
package Thread;
/**
*
* // 生产者消费者问题
* @author Muluo
* @create 2021-02-14 19:23
*/
public class CustomerAndProvide {
public static void main(String[] args) {
Data data = new Data();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "a").start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "b").start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "c").start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "d").start();
}
}
class Data{
private int num = 0;
public synchronized void decrement() throws InterruptedException {
while (num != 0) {
this.wait();
}
num++;
System.out.println(Thread.currentThread().getName() + "->" + num);
this.notifyAll();
}
public synchronized void increment() throws InterruptedException {
while (num == 0) {
this.wait();
}
num--;
System.out.println(Thread.currentThread().getName() + "->" + num);
this.notifyAll();
}
}
JUC
package Thread;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author Muluo
* @create 2021-02-14 19:45
*/
public class CustomerAndProvide2 {
public static void main(String[] args) {
Data2 data = new Data2();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
data.decrement();
}
}, "a").start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
data.increment();
}
}, "b").start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
data.decrement();
}
}, "c").start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
data.increment();
}
}, "d").start();
}
}
class Data2{
private int num = 0;
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
public void decrement() {
lock.lock();
try {
while (num != 0) {
condition.await();
}
num++;
System.out.println(Thread.currentThread().getName() + "->" + num);
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void increment() {
lock.lock();
try {
while (num == 0) {
condition.await();
}
num--;
System.out.println(Thread.currentThread().getName() + "->" + num);
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}