[Java] Java Controllerは、マルチスレッドのReentrantLockを一度に1つしか要求できません

ここに写真の説明を挿入

1。概要

背景コントローラーでクライアント要求を受け入れるプログラムがありますが、この要求の操作は非常に重いため、要求が終了した場合は要求を拒否する必要があります。これは時間のかかる操作だからです。また、複数の操作でエラーが報告されます。


@GetMapper()
public void do(){
    
    
   // 判断是否还有在运行的线程
   // 线程是否允许完毕,如果没有,那么直接返回
   // 否则就创建一个新的线程,然后立马返回,让线程在后台慢慢的跑
}

@GetMapper()
public void do2(){
    
    
   // 判断是否还有在运行的线程
   // 线程是否允许完毕,如果没有,那么直接返回
   // 否则就创建一个新的线程,然后立马返回,让线程在后台慢慢的跑
}

上記の2つの方法のいずれかが実行されている限り、新しいスレッドを作成することはできません。

2.スキーム1

ロックの実装


ExecutorService single = Executors.newSingleThreadExecutor();
private final ReentrantLock lock = new ReentrantLock();

/**
     * 测试点:测试controoler中阻塞一个程序,每次只能一个程序过来
     * @throws InterruptedException
     * @throws ExecutionException
     */
@Test
 public void test2() throws InterruptedException, ExecutionException {
    
    
     redo1();
     System.out.println("执行第一个");
     System.out.println("执行第2个");
     redo1();

     Thread.sleep(Integer.MAX_VALUE);
 }


private void redo1() {
    
    
        if (lock.isLocked()) {
    
    
            System.out.println("被锁在直接返回");
            return;
        }

        lock.lock();
        try {
    
    
            System.out.println("进行提交");
            feature = single.submit(new DeleteKafkaTopicRunable1(lock));
        } catch (Exception e) {
    
    
            System.out.println("执行释放锁111");
            lock.unlock();
        }
    }

DeleteKafkaTopicRunable1子スレッド

package com.java.thread.demo.pool.single;

import java.util.concurrent.locks.ReentrantLock;

/**
 * @author: chuanchuan.lcc
 * @date: 2020-11-04 19:23
 * @modifiedBy: chuanchuan.lcc
 * @version: 1.0
 * @description:
 */
public class DeleteKafkaTopicRunable1 implements Runnable {
    
    

    private  ReentrantLock lock = null;

    public DeleteKafkaTopicRunable1(ReentrantLock lock) {
    
    
        this.lock = lock;
    }

    @Override
    public void run() {
    
    
        System.out.println("线程开始运行"+Thread.currentThread().getName());
        try {
    
    
            Thread.sleep(3000L);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("线程运行结束"+Thread.currentThread().getName());
        System.out.println(lock.isLocked());

        System.out.println("开始释放锁");
        // 这里是最坑爹的,这里居然不能释放锁
        lock.unlock();
        System.out.println("释放锁1");
    }

}

これが最も不正行為であり、ここでロックを解除することはできません。プログラムへの参加は1回のみです。

3.オプション2呼び出し可能

 	@Test
    public void test4() throws InterruptedException, ExecutionException {
    
    
        redo();
        System.out.println("执行第一个");
        System.out.println("执行第2个");
        redo();

        Thread.sleep(Integer.MAX_VALUE);
    }




    private void redo() throws ExecutionException, InterruptedException {
    
    
        if (feature != null) {
    
    
            Boolean result = null;
            Boolean result1 = null;
                result1 = (Boolean) feature.isDone();
//                result = (Boolean) feature.get(1000L, TimeUnit.SECONDS);
            System.out.println(result);
            System.out.println(result1);
            if(result1){
    
    
                lock.unlock();
            }else {
    
    
                System.out.println("被锁在直接返回");
                return;
            }
        }
        if (lock.isLocked()) {
    
    
            System.out.println("被锁在直接返回");
            return;
        }

        lock.lock();
        try {
    
    
            System.out.println("进行提交");
            feature = single.submit(new DeleteKafkaTopicRunable());
        } catch (Exception e) {
    
    
            System.out.println("执行释放锁111");
            lock.unlock();
        }
        Thread.sleep(2000L);
    }

DeleteKafkaTopicRunable方法

package com.java.thread.demo.pool.single;

import java.util.concurrent.Callable;

/**
 * @author: chuanchuan.lcc
 * @date: 2020-11-04 17:23
 * @modifiedBy: chuanchuan.lcc
 * @version: 1.0
 * @description:
 */
public class DeleteKafkaTopicRunable implements Callable<Boolean> {
    
    

    @Override
    public Boolean call() throws Exception {
    
    
        System.out.println("线程开始运行"+Thread.currentThread().getName());
        try {
    
    
            Thread.sleep(1000L);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("线程开始运行结束"+Thread.currentThread().getName());
        return false;
    }
}

これは、実装がより簡単で簡単です。

4.マルチスレッド拒否戦略

おすすめ

転載: blog.csdn.net/qq_21383435/article/details/109501618