面试官让我解释一下JUC,我懵了,沉思片刻我竟然这样做了.....

前几天面试的时候,前几个问题一切顺利,但我从眼前的面试官,一个三十左右的男子的脸上看不到任何满意的表情;我心里略带紧张,只觉得心里有说不出的不对劲,但是此时的我不敢懈怠,虽说我刚刚回答出了面试官的问题,但那个问题之后,他足足有十秒没有说话,我只感觉时间停止,呼吸甚至都有些困难,又不敢深呼吸,椅子上也好像多了几只蚂蚁,在啃咬我的屁股。

"你说说你对JUC的理解吧!"

略带磁性的嗓音响起,面试官开口了。

我咽了口唾沫,看向面试官。

面试官那略带沧桑的脸庞上深邃的眼睛,就算是戴上眼睛,也能感觉到他问题的"善意",深呼吸,头晕是正常的!

"JUC!"

"握草!"

又是这么宽泛的问题,我上来就是一个叫苦不迭!

大脑开始飞速运转,之前复习的知识开始如同磁带的塑料带子一般飞速转动,试图找到一些相关知识:

什么是JUC?

哦哦哦!对,JUC是Java.util.concurrent 的缩写,util是工具,concurrent 是并发的意思,哦哦哦!那么JUC大差不差就是与并发相关的

与并发相关的,并发就是多个任务同时出现,交由一个线程去处理,但是在这期间会出现一些数据安全问题,也就是我们常说的线程安全问题,那么根据线程安全问题,应该是去想如何保证数据安全(先把线程创建什么的扔在一边,自我感觉面试官的重点不是在这里),保证数据安全首先想到的应该是原子性操作,再然后就应该想如何保证原子性操作:原子类,volatile关键字,锁机制。

好,差不多,应该就是这些,有了这些应该可以说一会儿,剩下的已经没有时间去想了。

思考了大约三十秒钟,我平复了一下呼吸,有些小自信的开始说道:

"JUC呢其实java.util.concurrent包的缩写,这个包下的主要内容就是与并发相关的,包括一些并发容器类,保证原子操作以及锁机制等等。"

我说完后沾沾自喜,这句话在当时我看来,虽然说不完全正确,但还是沾边儿的,最重要的是,我把我会的说了出来,也给面试官留了引导。

只见面试官看了看我,并没有什么想问的。

以我灵活的小脑袋瓜,自然理解这是什么意思,继续说呗!

这题我会!

"在一开始接触到JUC的时候,我是没有概念的,这是在学完之后才能理解JUC到底是干什么的,在一开始学习JUC的时候,首先接触到的是线程,线程与进程是不同的,它比进程小,是进程的组成单位,线程的普通创建方式有三种一种是直接创建Thread的实现类(自定义的)第二种是通过实现Runnale接口并将其作为参数传入Thread,第三种是通过Collable接口来进行重写(Collable重写接口可以细说,它是作为参数传入了FutrueTask中,而FutrueTask因为是间接实现了Runnale接口,所以可以作为参数传入Thread中创建);还有就是可以通过线程池进行创建,线程池的创建方式也有很多种,我知道的有:1.可以规定线程池的最大线程数量(这个其实是核心线程作为最大线程的);2.创建性能线程池,之所以是性能就是无需去规定其里边的线程数;3.创建单个线程的线程池;4.还有创建可以做延时任务的线程池。

但是我通过学习和查资料,发现阿里巴巴提供的开发手册其实是不推荐使用这些方式创建的线程池,而是推荐使用ThreadPoolExecutor去直接创建,而我们需要向其传入七大参数1.核心线程数量(CoreSize);2.最大线程数量(Maximum);3.空闲线程存活时间(KeepAliveTime);4.存活时间单位(TimeUnit);5.线程创建工厂(ThreadFacotry);6.工作队列(workQueue);7.任务拒绝策略(RejectExceptionHanlder);

工作队列其实也叫做阻塞队列,常见的有七种,但是常用的两种其实就够了;这七种有:1.ArrayBlockingQueue,它是基于数组组成的有界阻塞队列,它的底层是一个定长的数组,但是内部的消费者和生产者是共用一把锁的,读写并不分离,至于为什么不分离,看了一些解释,就是说它是基于数组操作的,写入和获取是足够轻巧的,也就不再需要去采用单独的锁去给代码带来额外的复杂性。这一点是和2. LinkedBlockingQueue区分开的,因为LinkedBlockingQueue它是基于链表的有界阻塞队列,它的边界其实就是Integer的最大值,而内部是采用读写分离的锁。3.DelayQueue,它是等待时间过了,才可以获取元素,它是没有边界的阻塞队列,但是具体底层没有了解;4.PriorityBlockingQueue是需要传入一个比较器Compator对象,它不会阻塞生产者,会在没有数据的时候阻塞消费者;5.SynchronusQueue它并没有缓冲区,生产者生产数据必须等到消费者来消费数据,否则等待;6.LinkedTransferQueue也是比较特殊的,它的特殊之处在于当消费者来取数据时,发现没有数据时,则会创建一个为null的节点(具体不清楚),并进行等待,等待生产者来消费数据的时候,判断队列为空之后,直接生产到结点中,并唤醒消费者进行消费;7.LinkedBlockingDeque是由链表组成的双向阻塞队列,在生产者生产数据时,队列满了阻塞,消费者发现队列没有数据也阻塞,前面两种是比较常用的,后面的五种我只是简单了解了一下。"

说完这些我感觉应该差不多了,毕竟也说了好一会儿了,便停了下来,等待面试官的反应。

"没有了吗?"

"......"

好好好!

我又想了想,之前好像看到过JUC的辅助类,这个应该也可以说。

"juc中有些辅助类,在并发场景做辅助工具使用,例如有CutDownLatch辅助类,它的作用是可以设置一个屏障,这个屏障是使用计时器来实现的,在每个线程持有这个对象后,每进行一次操作调用cutdown()方法进行计数器减一操作,让指定的线程去调用await()方法,等到规定的计时器数量为0时,指定线程才会被唤醒;它其实是辅助线程通讯的;还有CycliBarrier,它的作用是设置一个屏障数,每次调用await()方法,都会屏障加1,等到加到指定值之后才会之后指定任务,这个是可以循环的,而CutDownLatch是不可以循环的;Semaphore,它的作用是控制并发的任务数,通过acquire()方法进行计数,每次计数之后都会调用release()去释放;Exchager,它是用于交换数据的,需要有两个或多个线程进行数据交换,调用exchange()方法完成。"

"嗯.....你觉得你对自己的回答满意吗?"

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值