Semáforo de JDK a mano

Prepensar

En primer lugar, aclare que la reducción de picos y la limitación de corriente no necesariamente tienen que usar colas MQ. De hecho, JDK nos proporciona un buen entorno. La función principal de Semaphore es [tiempo para el espacio], que es la solicitud que no podemos manejar ahora. Déjelo esperar un momento. Sí, después de que tengamos espacio libre para tratar con él, esto se debe principalmente a que el JDK ya ha logrado la reducción de picos y la limitación de corriente, por lo que podemos profundizar más.

La idea principal

Semaphore no es más que poner solicitudes que no se pueden procesar en la cola y sacarlas cuando se puedan procesar.

Clases más utilizadas

  • LinkedBlockingQueue: Por supuesto, la cola es indispensable aquí, por supuesto, esta cola tiene otra función, quien devuelva el token
  • AtomicInteger: determina principalmente cuándo bloquear
  • LockSupport: cambiar el estado del hilo

¡Se acabó la explicación! !

/**
     * 用于存储线程
     */
    private LinkedBlockingQueue<Thread> requestQueue = new LinkedBlockingQueue<>();
    /**
     * 外部传入令牌数量,用于什么时候让线程进入阻塞
     */
    private AtomicInteger tokenNumber;

    public MySemaphore(Integer tokenNumber) {
    
    
        this.tokenNumber = new AtomicInteger(tokenNumber);
    }

¡Este paso no tiene nada que decir para continuar! !

/**
     * 是否能获取令牌
     */
    public boolean tryAcquire() {
    
    
        if (!requestQueue.contains(Thread.currentThread())) {
    
    
            requestQueue.add(Thread.currentThread());
        }
        return tokenNumber.get() > 0;
    }

Determine principalmente si se puede obtener el token y no coloque subprocesos duplicados en la cola

/**
     * 获取令牌
     */
    public void acquire() {
    
    
        //当前令牌捅中还有令牌,则进行自减,没有则阻塞进入等待队列
        if ( tryAcquire()) {
    
    
            tokenNumber.decrementAndGet();
        } else {
    
    
            LockSupport.park();
        }
    }

Obtener una ficha, poner la ficha en el barril a -1, si no, bloquear

/**
     * 用完了释放令牌 只有是当前队列中的线程才允许释放令牌,并且检测是否在休眠线程,是则唤醒
     */
    public void release() {
    
    
        if (requestQueue.remove(Thread.currentThread())) {
    
    
            tokenNumber.incrementAndGet();
            for (Thread thread : requestQueue) {
    
    
                if (!thread.getState().equals(Thread.State.RUNNABLE)) {
    
    
                    LockSupport.unpark(requestQueue.peek());
                }
            }
        }
    }

Por supuesto, no es difícil pedir prestado y volver a tomar prestado. La consideración principal aquí es si el hilo en la cola actual devuelve el token y el estado del hilo. La razón principal es despertarse y no volver a despertar. Por supuesto, este lugar Solo se considera que no se despertará si se despierta, y el otro estado del hilo no se ha considerado
PS: No es justo aquí, pero no se ha realizado ¡Lo principal es que es doloroso no despertar! ¡No dude en aclararme si lo ve! ! !

Supongo que te gusta

Origin blog.csdn.net/cj181jie/article/details/108734434
Recomendado
Clasificación