阿里面试官:如何实现三个线程交替循环打印?

问题:如何实现三个线程交替循环打印?

示例:线程1打印A,线程2打印B,线程3打印C,要求交替打印,并且可以循环打印。
输出结果类似:ABCABCABC

这道题的难度是五颗星,在面试中也会经常遇到,如果是第一次见到这道题,很难在短时间内想出合理的解决方案。
如果只要求交替打印一次的话,实现比较简单,可以用Thread.join()方法,一个线程等待另一个线程执行完成。
现在要求循环打印,就涉及线程间通信,必须要用到锁,一把锁肯定不够。例如线程1释放锁之后,线程2和线程3都可能获取到锁,是随机的,现在要求必须是线程2获取到锁,所以需要三把锁。

执行过程:
线程1获取A锁,打印A,释放B锁;
线程2获取B锁,打印B,释放C锁;
线程3获取C锁,打印C,释放A锁;
循环执行;

可以用Synchronized或者ReentrantLock实现,不过它们不能控制线程启动后的执行顺序。因为三个线程启动后,都等待CPU调度执行,而CPU调度的顺序又是随机的,所以不能保证线程1先执行。

有个可以控制线程启动后执行顺序,又简单的实现方式,就是用Semaphore(信号量),它可以控制共享资源的访问个数。

使用方式:

  1. 初始化的时候,指定共享资源的个数

    // 初始化一个资源
    Semaphore semaphore = new Semaphore(1);
    
  2. 获取资源,获取资源后,semaphore资源个数减1,变成0,其他线程再获取资源的时候就会阻塞等待

semaphore.acquire();
  1. 释放资源,semaphore资源个数加1,其他阻塞的线程就可以获取到资源了
semaphore.release();

代码实现:


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值