生产者和消费者问题:Synchronized 版
Synchronized:wait 、notify
package pers.vincent.matrix.subject.juc;
public class JucTest3 {
public static void main(String[] args) {
NoTest noTest = new NoTest();
new Thread(()->{
for (int i = 0; i < 60; i++) {
try {
noTest.add();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "A").start();
new Thread(()->{
for (int i = 0; i < 60; i++) {
try {
noTest.del();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "B").start();
}
}
//
class NoTest{
private int num = 0 ;
public synchronized void add() throws InterruptedException {
if(num!=0){
this.wait();
}
num++;
this.notifyAll();
}
public synchronized void del() throws InterruptedException {
if(num==0){
this.wait();
}
num--;
this.notifyAll();
}
}
问题存在:if 在更多线程的情况下会存在虚假唤醒问题
if 拿到之后不会等待,while 会等待,所以当多个线程操作的时候,循环需要时候 while()
JUC 版 生产者和消费者问题
package pers.vincent.matrix.subject.juc;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class JucTest4 {
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (int i = 0; i < 5; i++) {
data.in();
}
}, "A").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
data.out();
}
}, "B").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
data.in();
}
}, "C").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
data.out();
}
}, "D").start();
}
}
class Data{
private int num = 0;
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
public void in(){
try {
lock.lock();
while(num!=0){
condition.await();
}
num++;
condition.signalAll();
System.out.println(Thread.currentThread().getName()+num);
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void out(){
try {
lock.lock();
while(num==0){
condition.await();
}
num--;
condition.signalAll();
System.out.println(Thread.currentThread().getName()+num);
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
Condition 的作用**: **精准的通知和唤醒线程