昨天面试,让我当场手撕下线程池的代码,全程懵,还好镇定住进个二面,发现最后还是挂。
回来从新审视了下自己的水平,发现没有水平。滚去学习了......
简单实现线程池:
回来大致看了下又结合面试官的那意思,现场大概就是让我实现两部分,一个就是线程池,另一个是那些源源不断的线程。线程池这块:单例实现一个线程池,写一个阻塞队列或者List之类的来存储预先打开的线程,随来随用,没有的话在去创建线程在开启,然后就是具体实施。线程这部分估计就是:你可以通过你想要的方法创建线程,我觉得这块可能在考我怎么用wait和notifyAll吧。然后具体怎么重写run方法吧。回来看了看别人写的代码,我觉得现场撕的话能满足这些应该就差不多了。这个是敲的,也借鉴了别人的。
撕线程池我发现还有一系列知识点
比如,也可以这么用run方法啊,你去创建一个Runnable的对象,然后直接用该对象调用run方法,也可以等同于一个线程实例对象开启线程后再调用run方法,也不知道我想的错没错。
通过这个还可以检查你怎么手撕单例模式,好几种呢,都可以撕,最好还是内部类那种方法,比较受欢迎,那个双重检查不好尽量不要用哈。
线程池中的阻塞队列,还有生产者消费者模式,都可以简单复习了,也可以手撕生产者消费者模式,这个就是三块了,一块生产者,一块消费者,还有中间的缓冲部分。具体实现我在想想下次补上。
阻塞队列也可以深问:我记得华为面试的时候问了下我如何实现无锁队列,我懵。后来回来看书看到了ConcurrentLinkedQueue,还有一系列并发容器和框架,发现有种叫Disruptor的框架很好进行了无锁队列实现,他用的是环形队列,非常适合生产者消费者,具体内部怎么实现的呢?就是因为是环形队列,这样就只对外提供一个cursor指针,这样既可以进队也可以出队,完美。如何很快的获得位置,就用sequence&(queueSize-1)。在生产者和消费者读写数据时用CAS操作来减少上下文切换的时间。
不知道为啥自己还联想到了银行家算法,这个就是如何避免死锁了,具体银行家算法是如何运作的呢?
银行家算法:我自己理解,就是现在我有很多资源,你要过来借用,这样的话就得看我有的资源够不够你用,如果够的话,我借给你,我减去相应数量的资源,你去用,这时候别人过来也想借,还是得进行一样的过程,当然了你借完得还我。这期间还有一个很重要的过程就是判断安全性,其实就是不够不接,够才借,系统不是一下子就把资源分配出去的,是计算了你要的资源和我有的,符合之后判定安全与否才进行分配。但是我觉得面试说这些不够专业,照抄了一下四点核心吧:
银行家规定:
1当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客(试探性分配)。
2顾客可以分期贷款,但贷款的总数不能超过最大需求量(可能一次并不能满足所需要的全部资源)。
3当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款(不存在死锁)。
4当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金(运行后释放)。
今天就写到这了。