packagecom.sgz.pc;/**
* 日期:2022/8/28 - 11:59
* 需求:
* 线程之间的通信问题:生产者和消费者问题!等待唤醒,通知唤醒
* 线程交替执行 A B 操作同一个变量 num = 0
* A num + 1
* B num - 1
*/publicclassDemo01{publicstaticvoidmain(String[] args){Data data =newData();newThread(()->{for(int i =0; i <10; i++){try{
data.increment();}catch(InterruptedException e){
e.printStackTrace();}}},"A").start();newThread(()->{for(int i =0; i <10; i++){try{
data.decrement();}catch(InterruptedException e){
e.printStackTrace();}}},"B").start();}}// 判断等待,业务,通知classData{// 数字 资源类privateint number =0;// +1 只要是并发就有锁publicsynchronizedvoidincrement()throwsInterruptedException{if(number !=0){// 0 number不等于0就等待,number等于0就干活// 等待this.wait();}
number++;System.out.println(Thread.currentThread().getName()+"=>"+ number);// 通知其它线程,我+1完毕了this.notifyAll();}// -1publicsynchronizedvoiddecrement()throwsInterruptedException{if(number ==0){// 1 number等于0就等待,number不等于0就干活// 等待this.wait();}
number--;System.out.println(Thread.currentThread().getName()+"=>"+ number);// 通知其它线程,我-1完毕了this.notifyAll();}}
2、代码案例(4个线程)if 改为 while 判断
以上使用 if 存在问题, A,B,C,D 4个线程会存在虚假唤醒,官方文档中写的 java.lang.Object 下的 wait
packagecom.sgz.pc;/**
* 日期:2022/8/28 - 11:59
* 需求:
* 线程之间的通信问题:生产者和消费者问题!等待唤醒,通知唤醒
* 线程交替执行 A B 操作同一个变量 num = 0
* A num + 1
* B num - 1
*/publicclassDemo01{publicstaticvoidmain(String[] args){Data data =newData();newThread(()->{for(int i =0; i <10; i++){try{
data.increment();}catch(InterruptedException e){
e.printStackTrace();}}},"A").start();newThread(()->{for(int i =0; i <10; i++){try{
data.decrement();}catch(InterruptedException e){
e.printStackTrace();}}},"B").start();newThread(()->{for(int i =0; i <10; i++){try{
data.increment();}catch(InterruptedException e){
e.printStackTrace();}}},"C").start();newThread(()->{for(int i =0; i <10; i++){try{
data.decrement();}catch(InterruptedException e){
e.printStackTrace();}}},"D").start();}}// 判断等待,业务,通知classData{// 数字 资源类privateint number =0;// +1 只要是并发就有锁publicsynchronizedvoidincrement()throwsInterruptedException{while(number !=0){// 0 number不等于0就等待,number等于0就干活// 等待this.wait();}
number++;System.out.println(Thread.currentThread().getName()+"=>"+ number);// 通知其它线程,我+1完毕了this.notifyAll();}// -1publicsynchronizedvoiddecrement()throwsInterruptedException{while(number ==0){// 1 number等于0就等待,number不等于0就干活// 等待this.wait();}
number--;System.out.println(Thread.currentThread().getName()+"=>"+ number);// 通知其它线程,我-1完毕了this.notifyAll();}}
三、JUC版
1、代码案例(4个线程)
packagecom.sgz.pc;importjava.util.concurrent.locks.Condition;importjava.util.concurrent.locks.Lock;importjava.util.concurrent.locks.ReentrantLock;/**
* 日期:2022/8/28 - 11:59
* 需求:
* 线程之间的通信问题:生产者和消费者问题!等待唤醒,通知唤醒
* 线程交替执行 A B 操作同一个变量 num = 0
* A num + 1
* B num - 1
*/publicclassDemo02{publicstaticvoidmain(String[] args){Data data =newData();newThread(()->{for(int i =0; i <10; i++){try{
data.increment();}catch(InterruptedException e){
e.printStackTrace();}}},"A").start();newThread(()->{for(int i =0; i <10; i++){try{
data.decrement();}catch(InterruptedException e){
e.printStackTrace();}}},"B").start();newThread(()->{for(int i =0; i <10; i++){try{
data.increment();}catch(InterruptedException e){
e.printStackTrace();}}},"C").start();newThread(()->{for(int i =0; i <10; i++){try{
data.decrement();}catch(InterruptedException e){
e.printStackTrace();}}},"D").start();}}// 判断等待,业务,通知classData{// 数字 资源类privateint number =0;Lock lock =newReentrantLock();Condition condition = lock.newCondition();// condition.await(); // 等待// condition.signalAll(); // 唤醒全部// +1 只要是并发就有锁publicvoidincrement()throwsInterruptedException{
lock.lock();try{// 业务代码while(number !=0){// 0 number不等于0就等待,number等于0就干活// 等待
condition.await();}
number++;System.out.println(Thread.currentThread().getName()+"=>"+ number);// 通知其它线程,我+1完毕了
condition.signalAll();}catch(Exception e){
e.printStackTrace();}finally{
lock.unlock();}}// -1publicvoiddecrement()throwsInterruptedException{
lock.lock();try{while(number ==0){// 1 number等于0就等待,number不等于0就干活// 等待
condition.await();}
number--;System.out.println(Thread.currentThread().getName()+"=>"+ number);// 通知其它线程,我-1完毕了
condition.signalAll();}catch(Exception e){
e.printStackTrace();}finally{
lock.unlock();}}}