默认的情况下cpu是在随机切换线程,那你邮箱多个线程可以有规律的执行,那么多线程之间需要一些协调通信;
Demo:多线程按照顺序调用:A->B->C
三个线程启动,要求:
- AA答应5次,BB答应10次,CC打印15次
- 接着
- AA答应5次,BB答应10次,CC打印15次
- …
- 就这样重复10轮
需要线程按照这就涉及到信号量:
实现:
/**
* 多线程按循序调用,实现A->B->C
* 三个线程启动,要求:
* AA答应5次,BB答应10次,CC打印15次
* 接着
* AA答应5次,BB答应10次,CC打印15次
* ..
* 就这样重复10轮
*
*
* @Author:LRC
* @Date:9:37 上午 2020/7/4
*/
class ShareData{
private int num = 1;//当为1的时候对应AA,2:BB,3:CC
private Lock lock = new ReentrantLock();
private Condition cd1 = lock.newCondition();
private Condition cd2 = lock.newCondition();
private Condition cd3 = lock.newCondition();
public void print5(int total){
lock.lock();
try {
//判断
while (num!=1){
cd1.await();
}
//干活
for (int i = 1; i <=5 ; i++) {
System.out.println(Thread.currentThread().getName()+":\t"+ total+"\t"+i);
}
num=2;
//通知
cd2.signal();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void print10(int total){
lock.lock();
try {
//判断
while (num!=2){
cd2.await();
}
//干活
for (int i = 1; i <=10 ; i++) {
System.out.println(Thread.currentThread().getName()+":\t"+ total+"\t"+i);
}
num=3;
//通知
cd3.signal();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void print15(int total){
lock.lock();
try {
//判断
while (num!=3){
cd3.await();
}
//干活
for (int i = 1; i <=15 ; i++) {
System.out.println(Thread.currentThread().getName()+":\t"+ total+"\t"+i);
}
num=1;
//通知
cd1.signal();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
public class ThreadOrderAccess {
public static void main(String[] args) {
ShareData shareData = new ShareData();
new Thread(()->{
for (int i = 1; i <= 10 ; i++) {
shareData.print5(i);
}
},"AA").start();
new Thread(()->{
for (int i = 1; i <= 10 ; i++) {
shareData.print10(i);
}
},"BB").start();
new Thread(()->{
for (int i = 1; i <= 10 ; i++) {
shareData.print15(i);
}
},"CC").start();
}
}
1、有顺序通知,需要有标识位
2、有一个锁Lock,3把钥匙Condition
3、判断标志位
4、输出线程名+第几次+第几轮
5、修改标志位,通知下一个