生产者消费者问题
synchronized:wait notify
/*线程之间的通信问题,生产者和消费者问题 通知唤醒,等待唤醒
* 线程交替进行,A B操作统一变量 num=0
* A num+1
* B num-1
* */
public class Product {
public static void main(String[] args) {
Data data=new Data();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"product").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"consumer").start();
}
}
class Data{
//资源类
private int num=0;
//+1
public synchronized void increment() throws InterruptedException {
/*等待*/
if(num!=0)
{
//等待
this.wait();
}
/*业务*/
num++;
System.out.println(Thread.currentThread().getName()+"=>"+num);
/*通知*/
//通知线程B,已经增加过了
this.notifyAll();
}
//-1
public synchronized void decrement() throws InterruptedException {
/*等待*/
if(num==0)
{
//等待
this.wait();
}
/*业务*/
num--;
System.out.println(Thread.currentThread().getName()+"=>"+num);
/*通知*/
//通知线程A,已经减少过了
this.notifyAll();
}
}
问题:A,B,C,D 四个线程时还安全吗?
if判断只会判断一次。防止虚假唤醒
等待改为while判断
while(num==0)
{
//等待
this.wait();
}
JUC版生产者消费者
public class Product2 {
public static void main(String[] args) {
Data2 data=new Data2();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"product").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"product1").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"consumer").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"consumer1").start();
}
}
class Data2{
//资源类
private int num=0;
Lock lock=new ReentrantLock();
Condition condition = lock.newCondition();
//+1
public void increment() throws InterruptedException {
/* Condition condition = lock.newCondition();
condition.await();//等待
condition.signal();//唤醒全部*/
/*等待*/
/*业务*/
lock.lock();
try {
while(num!=0)
{
condition.await();
}
num++;
System.out.println(Thread.currentThread().getName()+"=>"+num);
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
/*通知*/
//通知线程B,已经增加过了
}
//-1
public void decrement() throws InterruptedException {
/*等待*/
/*业务*/
lock.lock();
try {
while(num==0)
{
//等待
condition.await();
}
num--;
System.out.println(Thread.currentThread().getName()+"=>"+num);
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
/*通知*/
//通知线程A,已经减少过了
}
}
Condition 精准通知和唤醒线程
/*
* A执行完调用B,B执行完调用C*/
public class Product3 {
public static void main(String[] args) {
data3 data=new data3();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.printA();
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.printB();
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.printC();
}
},"C").start();
}
}
class data3{ //资源类
Lock lock=new ReentrantLock();
private int num=1;//1 A, 2 B, 3 C
//监视器
Condition condition = lock.newCondition();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
public void printA(){
lock.lock();
try {
while(num!=1) {
condition.await();
}
System.out.println("A");
num=2;
condition1.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printB(){
lock.lock();
try {
while(num!=2) {
condition1.await();
}
System.out.println("B");
num=3;
condition2.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printC(){
lock.lock();
try {
while(num!=3) {
condition2.await();
}
System.out.println("C");
num=1;
condition.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}