线程间通信的模型有两种:共享内存和消息传递,以下方式都是基本这两种模型来实现的。我们来基本一道面试常见的题目来分析
场景—-两个线程,一个线程对当前数值加 1,另一个线程对当前数值减 1,要求用线程间通信
1. synchronized方案
package com.atguigu.test;/*** volatile 关键字实现线程交替加减*/public class TestVolatile {/*** 交替加减* @param args*/public static void main(String[] args){DemoClass demoClass = new DemoClass();new Thread(() ->{for (int i = 0; i < 5; i++) {demoClass.increment();}}, "线程 A").start();new Thread(() ->{for (int i = 0; i < 5; i++) {demoClass.decrement();}}, "线程 B").start();}}package com.atguigu.test;class DemoClass{//加减对象private int number = 0;/*** 加 1*/public synchronized void increment() {try {while (number != 0){this.wait();}number++;System.out.println("--------" + Thread.currentThread().getName() + "加一成功----------,值为:" + number);notifyAll();}catch (Exception e){e.printStackTrace();}}/*** 减一*/public synchronized void decrement(){try {while (number == 0){this.wait();}number--;System.out.println("--------" + Thread.currentThread().getName() + "减一成功----------,值为:" + number);notifyAll();}catch (Exception e){e.printStackTrace();}}}
2. Lock方案
package com.atguigu.test;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;class DemoClass{//加减对象private int number = 0;//声明锁private Lock lock = new ReentrantLock();//声明钥匙private Condition condition = lock.newCondition();/*** 加 1*/public void increment() {try {lock.lock();while (number != 0){condition.await();}number++;System.out.println("--------" + Thread.currentThread().getName() + "加一成功----------,值为:" + number);condition.signalAll();}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}/*** 减一*/public void decrement(){try {lock.lock();while (number == 0){condition.await();}number--;System.out.println("--------" + Thread.currentThread().getName() + "减一成功----------,值为:" + number);condition.signalAll();}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}}
4. 线程间定制化通信
4.1 案例介绍
==问题: A 线程打印 5 次 A, B 线程打印 10 次 B, C 线程打印 15 次 C,按照此顺序循环 10 轮==
4.2 实现流程
package com.atguigu.test;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;class DemoClass{//通信对象:0--打印 A 1---打印 B 2----打印 Cprivate int number = 0;//声明锁private Lock lock = new ReentrantLock();//声明钥匙 Aprivate Condition conditionA = lock.newCondition();//声明钥匙 Bprivate Condition conditionB = lock.newCondition();//声明钥匙 Cprivate Condition conditionC = lock.newCondition();/*** A 打印 5 次*/public void printA(int j){try {lock.lock();while (number != 0){conditionA.await();}System.out.println(Thread.currentThread().getName() + "输出 A,第" + j + "轮开始");//输出 5 次 Afor (int i = 0; i < 5; i++) {System.out.println("A");}//开始打印 Bnumber = 1;//唤醒 BconditionB.signal();}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}/*** B 打印 10 次*/public void printB(int j){try {lock.lock();while (number != 1){conditionB.await();}System.out.println(Thread.currentThread().getName() + "输出 B,第" + j + "轮开始");//输出 10 次 Bfor (int i = 0; i < 10; i++) {System.out.println("B");}//开始打印 Cnumber = 2;//唤醒 CconditionC.signal();}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}/*** C 打印 15 次*/public void printC(int j){try {lock.lock();while (number != 2){conditionC.await();}System.out.println(Thread.currentThread().getName() + "输出 C,第" + j + "轮开始");//输出 15 次 Cfor (int i = 0; i < 15; i++) {System.out.println("C");}System.out.println("-----------------------------------------");//开始打印 Anumber = 0;//唤醒 AconditionA.signal();}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}}
测试类
package com.atguigu.test;/*** volatile 关键字实现线程交替加减*/public class TestVolatile {/*** 交替加减* @param args*/public static void main(String[] args){DemoClass demoClass = new DemoClass();new Thread(() ->{for (int i = 1; i <= 10; i++) {demoClass.printA(i);}}, "A 线程").start();new Thread(() ->{for (int i = 1; i <= 10; i++) {demoClass.printB(i);}}, "B 线程").start();new Thread(() ->{for (int i = 1; i <= 10; i++) {demoClass.printC(i);}}, "C 线程").start();}}

