Entrevistador: hablar de la diferencia entre el justo y el injusto bloqueo cerradura?

Pulgar hacia arriba de nuevo, un hábito, la búsqueda de micro-canales [ propilo Tercer Príncipe Ao ] afectadas las personas en esta herramienta de Internet Gouqietousheng.

En este artículo se GitHub github.com/JavaFamily ya se ha incluido, hay una línea completa sitios de prueba fabricantes entrevista, así como información sobre mi serie de artículos.

prefacio

La última vez que mencionamos el bloqueo optimista y pesimista, sabemos que hay muchos tipos de cerraduras, hablamos de hoy es simple, justo y bloqueo injusto bloquea la pareja, y se practican en nuestro código.

texto

Antes de empezar a hablar, permítanme decir algo sobre su definición tanto, para ayudarle a revisar o conoce.

cerraduras justas: múltiples hilos con el fin de aplicar un bloqueo para obtener un bloqueo, la rosca directamente en la cola a cola, la cola es siempre el primero en obtener el bloqueo.

  • Pros: Todos los hilos tienen acceso a los recursos, no se morirán de hambre en la cola.
  • Desventajas: El rendimiento se caen mucho, lo que además del primer hilo de cola, otros hilos bloquearán, hilos de bloqueo de la CPU son costo despertado será grande.

bloqueo injusto: múltiples hilos para adquirir el tiempo de bloqueo, irá directamente a tratar de conseguir, obtener menos, entrar en la cola de espera, si se puede llegar a ella directamente a la cerradura.

  • Ventajas: puede reducir la sobrecarga de la CPU del hilo de despertar, la eficiencia global serán de alto rendimiento, la CPU no tiene que tomar para despertar todas las discusiones se reducirá el número de hilos para evocar.
  • Contras: También pueden encontrar, y esto puede conducir a la mitad de la cola de hilo ha adquirido el bloqueo o no durante mucho tiempo no obtener un bloqueo, lo que lleva a la inanición.

Doy un ejemplo a su casa para hablar de la llanura, al igual que a los pocos días, finalmente encontraron un ejemplo de cómo cuando el día antes de ayer con los tres torcida ir a KFC a comprar cola de desayuno.

Ahora es el momento para el desayuno, Ao propileno quiere poner el desayuno KFC hacia adelante y encontró una gran cantidad de personas, y uno no pensaba en el pasado, a la cola, obediente, se alinean, por lo que todos sentimos es muy justo, primer servido, por lo que es cerraduras justas ligeramente.

Ese bloqueo es injusto, Ao propileno en el pasado para comprar el desayuno y se encontró que todos en la cola, pero esto poco de Ao escoria de propileno es como saltarse la cola, entonces él no le gustaría dirigir la primera que fue a la parte trasera de los huevos, granos de arroz son no, yo no digo nada para saltar la cola, sólo se soportó en silencio.

Pero de vez en cuando, los huevos van a subir, laminados en fila detrás de mí, yo también soy un matón, se alinean en voz baja a la parte posterior, para saltar la cola falló.

Introducción a un simple ejemplo, podríamos decir, Jardine C, esto lo sé ah.

我们是不是应该回归真正的实现了,其实在大家经常使用的ReentrantLock中就有相关公平锁,非公平锁的实现了。

大家还记得我在乐观锁、悲观锁章节提到的Sync类么,是ReentrantLock他本身的一个内部类,他继承了AbstractQueuedSynchronizer,我们在操作锁的大部分操作,都是Sync本身去实现的。

Sync呢又分别有两个子类:FairSync和NofairSync

他们子类的名字就可以见名知意了,公平和不公平那又是怎么在代码层面体现的呢?

公平锁:

你可以看到,他加了一个hasQueuedPredecessors的判断,那他判断里面有些什么玩意呢?

代码的大概意思也是判断当前的线程是不是位于同步队列的首位,是就是返回true,否就返回false。

我总觉得写到这里就应该差不多了,但是我坐下来,静静的思考之后发现,还是差了点什么。

上次聊过ReentrantLock了,但是AQS什么的我都只是提了一嘴,一个线程进来,他整个处理链路到底是怎样的呢?

公平锁到底公平不公平呢?让我们一起跟着丙丙走进ReentrantLock的内心世界。

上面提了这么多,我想你应该是有所了解了,那一个线程进来ReentrantLock这个渣男是怎么不公平的呢?(默认是非公平锁)

我先画个图,帮助大家了解下细节:

ReentrantLock的Sync继承了AbstractQueuedSynchronizer也就是我们常说的AQS

他也是ReentrantLock加锁释放锁的核心,大致的内容我之前一期提到了,我就不过多赘述了,他们看看一次加锁的过程吧。

A线程准备进去获取锁,首先判断了一下state状态,发现是0,所以可以CAS成功,并且修改了当前持有锁的线程为自己。

这个时候B线程也过来了,也是一上来先去判断了一下state状态,发现是1,那就CAS失败了,真晦气,只能乖乖去等待队列,等着唤醒了,先去睡一觉吧。

A持有久了,也有点腻了,准备释放掉锁,给别的仔一个机会,所以改了state状态,抹掉了持有锁线程的痕迹,准备去叫醒B。

这个时候有个带绿帽子的仔C过来了,发现state怎么是0啊,果断CAS修改为1,还修改了当前持有锁的线程为自己。

B线程被A叫醒准备去获取锁,发现state居然是1,CAS就失败了,只能失落的继续回去等待队列,路线还不忘骂A渣男,怎么骗自己,欺骗我的感情。

诺以上就是一个非公平锁的线程,这样的情况就有可能像B这样的线程长时间无法得到资源,优点就是可能有的线程减少了等待时间,提高了利用率。

现在都是默认非公平了,想要公平就得给构造器传值true。

ReentrantLock lock = new ReentrantLock(true);
复制代码

说完非公平,那我也说一下公平的过程吧:

线A现在想要获得锁,先去判断下state,发现也是0,去看了看队列,自己居然是第一位,果断修改了持有线程为自己。

线程b过来了,去判断一下state,嗯哼?居然是state=1,那cas就失败了呀,所以只能乖乖去排队了。

未命名文件 (https://tva1.sinaimg.cn/large/00831rSTly1gcxaojuen2j30oa0jxgmh.jpg)
未命名文件 (https://tva1.sinaimg.cn/large/00831rSTly1gcxaojuen2j30oa0jxgmh.jpg)

线程A暖男来了,持有没多久就释放了,改掉了所有的状态就去唤醒线程B了,这个时候线程C进来了,但是他先判断了下state发现是0,以为有戏,然后去看了看队列,发现前面有人了,作为新时代的良好市民,果断排队去了。

线程B得到A的召唤,去判断state了,发现值为0,自己也是队列的第一位,那很香呀,可以得到了。

总结:

总结我不说话了,但是去获取锁判断的源码,箭头所指的位置,现在是不是都被我合理的解释了,当前线程,state,是否是0,是否是当前线程等等,都去思考下。

鬼知道我为了画图,画了多少费稿,点个赞过分么?

课后作业

公平锁真的公平么?那什么层面不是绝对的公平,什么层面才能算公平?

我是敖丙,一个在互联网苟且偷生的工具人。

最好的关系是互相成就,各位的「三连」就是丙丙创作的最大动力,我们下期见!

文章持续更新,可以微信搜索「 三太子敖丙 」第一时间阅读,回复【资料】【面试】【简历】有我准备的一线大厂面试资料和简历模板,本文 GitHub github.com/JavaFamily 已经收录,有大厂面试完整考点,欢迎Star。

Supongo que te gusta

Origin juejin.im/post/5e7212b3f265da576e64bcd1
Recomendado
Clasificación