多个线程做排序,返回最早排序好的线程的结果

多个线程做排序,返回最早排序好的线程的结果

最近面天猫,面试官出了一道这样的题:

假设有一个排序方法,里面起了5个线程、分别用一个排序算法做排序操作,这个方法返回5个线程中最快排好序的结果。

这个问题肯定是问的juc下的那些新的同步锁,只是我一下子有点反应不过来,最终只想到一个countDownLatch,遗憾了(虽然就算答出来应该也过不了面试~)。

实际上这也就是一个生产者消费者问题:消费者是主线程,生产者是排序线程。生产者消费者问题直接看这篇博客:生产者消费者
但这个和普通的生产者消费者问题又不一样,普通的生产者也是加了锁的,一次只有一个生产者线程在运行,而这个题是要求5个线程一起排序。

这里我主要是想用juc下的那些同步锁来做这题(面试官也说了这是一道开放性的题目,能想多少答案就想多少)。好,现在也算复习下这些同步锁。看看回字到底有多少种写法。
这些同步锁我就不在这篇博文里写具体示例代码了,可以看这篇JUC下的一些同步锁
countDownLatch
countDownLatch是最容易想到的,new 一个countDownLatch,大小为1,主线程调用latch.await()方法阻塞住,5个线程同时排序,排序成功的线程调用latch.countDown,于是门栓放开,主线程运行并返回结果。

CyclicBarrier
cyclicBarrier是栅栏的意思,这个也可以实现这个题。new一个cyclicBarrier,大小为2,主线程调用barrier.await()方法,表示有一个线程阻塞在栅栏上了;5个线程排序成功后也调用barrier.await(),一旦栅栏上阻塞的线程到2了,栅栏放开,主线程和排序好的线程一起运行,主线程返回结果。

Semaphore
new一个大小为0的信号量,主线程semaphore.acquire()尝试获取信号量,由于信号量的大小为0获取不到,阻塞住;5个排序线程排序好后就把信号量++(调用semaphore.release()),任意一个线程++后主线程就能acquire到信号量而运行返回结果。

Exchanger
甚至连Exchanger都能实现。Exchanger是要2个线程都往这个容器里put值,才会交换并运行,否则阻塞住等另一个线程往容器里赋值。所以可以主线程往Exchanger里Exchanger.exchange(T t)一个值,然后阻塞住,排序线程排好序后也往Exchanger里放一个值,此时主线程继续运行,返回结果。

FutureTask和CompletableFuture
CompletableFuture用于管理多个FutureTask,这个能回答出来的话一定能加分
new 5个CompletableFuture,每个Future执行一个排序方法,然后调用CompletableFuture.anyOf(future1,future2,future3,future4,future5).join(),阻塞住并等待任意一个任务执行完毕后运行。
实际上线程池创建了5个线程去执行的任务。
详细可以看这篇博文最后线程池与CompletableFuture

BlockingQueue
最后,其实可以用阻塞队列来实现,new一个阻塞队列,里面元素为空,主线程去调用queue.take(),由于队列种没有值而被阻塞住。排序线程排好序后往queue中put一个值,主线程获取到并继续运行。
BlockingQueue有好多种实现,解析也可以看这篇BlockingQueue

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值