자바 간단 한 스 레 드 풀 실현

분할 실현 절차
아래 그림 을 보 세 요.
在这里插入图片描述
우선 우 리 는 스 레 드 탱크 에 대해 기능 분할 을 해 야 한다.
  • Thread Pool 은 바로 우리 의 스 레 드 풀 입 니 다.t1,t2,t3 는 세 개의 스 레 드
  • 를 대표 합 니 다.
  • Blocking Queue 대표 차단 대기 열
  • main 은 main 방법 을 대표 하 는 스 레 드
  • task 1,task 2,task 3 대표 가 수행 할 모든 임무
  • 지금 우 리 는 집행 절 차 를 정리 하고,여 기 는 간략 판 이 며,문장 뒤에 나 는 상세 판 을 제시 할 것 이다.
    在这里插入图片描述
    그래서 이때 우 리 는 몇 가지 종 류 를 만들어 야 하거나 몇 가지 캐릭터 를 만들어 야 한 다 는 것 을 알 게 되 었 다.
  • 스 레 드 탱크
  • 작업 스 레 드
  • 대기 열 차단
  • 거부 전략(뭐 하 는 거 야?스 레 드 수가 가득 찼 고 차단 대기 열 이 가득 찼 습 니 다.그리고 작업 이 차단 대기 열 에 들 어가 고 싶 을 때 이 작업 을 거절 할 수 있 습 니 다)
  • 실현 방식
    1.정책 거부
    
    /**
     *     
     */
    @FunctionalInterface
    interface RejectPolicy<T>{
    	//queue             ,task   
        void reject(BlockingQueue<T> queue,T task);
    }
    
    2.대기 열 차단
    우 리 는 네 가지 방법,획득 과 추가,시간 초과 획득 과 시간 초과 추 가 를 실현 해 야 한다.방법 이 실현 되 는 세부 사항 에 대해 나 는 대량의 주석 을 달 아 설명 했다.
    
    /**
     *     
     */
    class BlockingQueue<T>{
        //    
        private Deque<T> queue = new ArrayDeque<>();
    
        // 
        private ReentrantLock lock = new ReentrantLock();
    
        //       
        private Condition fullWaitSet = lock.newCondition();
    
        //       
        private Condition emptyWaitSet = lock.newCondition();
    
        //  
        private int capacity;
    
        public BlockingQueue(int capacity){
            this.capacity = capacity;
        }
    
        //        
        public T poll(long timeout, TimeUnit timeUnit){
            lock.lock();
            try {
                // timeout       
                long nanos = timeUnit.toNanos(timeout);
                while(queue.isEmpty()){
                    try {
                        if(nanos <= 0){
                            //  0,         ,       
                            return null;
                        }
                        //         
                        nanos = emptyWaitSet.awaitNanos(nanos);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                T t = queue.removeFirst();
                //     
                fullWaitSet.signal();
                return t;
            }finally {
                lock.unlock();
            }
        }
    
        //    
        public T take(){
            lock.lock();
            try{
                while(queue.isEmpty()){ //        ,              
                    try {
                         /*
                                          ,    emptyWaitSet          
                               ,            
                         */
                        emptyWaitSet.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                /*
                       。         ,                   
                                
                 */
                T t = queue.removeFirst();
                /*
                            Condition   ,            ,fullWaitSet        
                            ,             fullWaitSet
                 */
                fullWaitSet.signal();
                //    
                return t;
            }finally {
                lock.unlock();
            }
        }
    
        //    
        public void put(T task){
            lock.lock();
            try {
                while(queue.size() == capacity){    //      
                    try {
                        System.out.println("        "+task);
                        /*
                                           ,    ,       Condition       
                               ,            
                         */
                        fullWaitSet.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //       
                System.out.println("      "+task);
                //         
                queue.addLast(task);
                /*
                            Condition   ,            ,emptyWaitSet        
                            ,             emptyWaitSet
                 */
                emptyWaitSet.signal();
            }finally {
                lock.unlock();
            }
        }
    
        //         
        public boolean offer(T task,long timeout,TimeUnit timeUnit){
            lock.lock();
            try {
                long nanos = timeUnit.toNanos(timeout);
                while(queue.size() == capacity){
                    try {
                        if(nanos < 0){
                            return false;
                        }
                        System.out.println("        "+task);
                        //      ,          
                        nanos = fullWaitSet.awaitNanos(nanos);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("      "+task);
                queue.addLast(task);
                emptyWaitSet.signal();
                return true;
            }finally {
                lock.unlock();
            }
        }
    
        //      
        public int size(){
            lock.lock();
            try{
                return queue.size();
            }finally {
                lock.unlock();
            }
        }
    
        //      ,          ,       
        public void tryPut(RejectPolicy<T> rejectPolicy, T task){
            lock.lock();
            try {
                //        
                if(queue.size() == capacity){
                    rejectPolicy.reject(this,task);
                }else{  //   
                    System.out.println("      "+task);
                    queue.addLast(task);
                    emptyWaitSet.signal();
                }
            }finally {
                lock.unlock();
            }
        }
    }
    
    3.스 레 드 탱크 와 작업 스 레 드
    나 는 작업 라인 을 라인 탱크 의 내부 클래스 로 삼 아 실현 했다.변 수 를 쉽게 호출 할 수 있 습 니 다.
    
    /**
     *    
     */
    class ThreadPool{
        //    
        private BlockingQueue<Runnable> taskQueue;
    
        //    
        private HashSet<Worker> workers = new HashSet<>();
    
        //     
        private int coreSize;
    
        //         
        private long timeout;
    
        private TimeUnit timeUnit;
    
        private RejectPolicy<Runnable> rejectPolicy;
    
        public ThreadPool(int coreSize, long timeout, TimeUnit timeUnit, int queueCapacity,RejectPolicy<Runnable> rejectPolicy) {
            this.coreSize = coreSize;
            this.timeout = timeout;
            this.timeUnit = timeUnit;
            this.taskQueue = new BlockingQueue<>(queueCapacity);
            this.rejectPolicy = rejectPolicy;
        }
    
        //    
        public void execute(Runnable task){
            synchronized (workers){
                if(workers.size() <= coreSize){  //             
                    Worker worker = new Worker(task);
                    workers.add(worker);
                    //       ,    run  
                    worker.start();
                }else{
                    // 1)   
                    // 2)      
                    // 3)           
                    // 4)         
                    // 5)           
                    taskQueue.tryPut(rejectPolicy,task);
                }
            }
        }
    
        /**
         *     ,           
         */
        class Worker extends Thread{
            private Runnable task;
            public Worker(Runnable task){
                this.task = task;
            }
    
            @Override
            public void run() {
                //    
                // 1)   task    ,    
                // 2)   task     ,               
                while (task != null || (task = taskQueue.poll(timeout, timeUnit)) != null) {
                    try {
                        System.out.println("       " + task);
                        task.run();
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        //            
                        task = null;
                    }
                }
                synchronized (workers) {
                    System.out.println("worker    " + this);
                    workers.remove(this);
                }
            }
        }
    }
    
    전략 모드
    세심 한 동료 들 은 내 가 거부 전략 에서 23 가지 디자인 모델 의 전략 모델 을 사용 한 것 을 발견 했다.왜냐하면 나 는 거절 하 는 방식 을 죽 이지 않 고 호출 자 에 게 맡 겼 기 때문이다.
    JDK 스 레 드 풀 대비
    다음은 JDK 자체 스 레 드 풀 입 니 다.
    在这里插入图片描述
    경전의 7 대 핵심 매개 변수
  • corePoolSize:핵심 스 레 드 수
  • queueCapacity:작업 대기 열 용량(차단 대기 열)
  • max PoolSize:최대 스 레 드 수
  • keepAliveTime:스 레 드 남 은 시간
  • TimeUnit unit:시간 초과 단위
  • ThreadFactory threadFactory:스 레 드 공정
  • rejected ExecutionHandler:작업 거부 프로세서
  • 실제로 우리 가 이 룬 것 도 대동소이 하 다.다만 JDK 공식 은 더 복잡 하 다.
    JDK 스 레 드 실행 프로 세 스 맵
    在这里插入图片描述
    在这里插入图片描述
    스 레 드 탱크 의 상태 전환
    스 레 드 는 운영 체제 차원 에서 5 가지 상태 가 있다 는 것 을 알 고 있 습 니 다.
    在这里插入图片描述
  • 초기 상태:언어 차원 에서 만 스 레 드 대상 을 만 들 었 을 뿐 운영 체제 스 레 드 와 연결 되 지 않 았 습 니 다
  • 실행 가능 한 상태(준비 상태):이 스 레 드 가 생 성 되 었 음(운영 체제 스 레 드 와 연 결 됨)을 말 합 니 다.CPU 에서 실행 할 수 있 습 니 다
  • 실행 상태:CPU 타임 시트 가 실 행 된 상 태 를 가 져 온 것 을 말 합 니 다.CPU 타임 시트 가 다 떨 어 지면[실행 상태]에서[실행 가능 상태]로 전환 되 고 스 레 드 의 컨 텍스트 전환
  • 을 초래 할 수 있 습 니 다.
  • 차단 상태
  • BIO 가 파일 을 읽 고 쓰 는 등 차단 API 를 호출 하면 이 스 레 드 는 실제 CPU 를 사용 하지 않 고 스 레 드 컨 텍스트 전환 을 초래 하여[차단 상태]
  • 에 들 어 갈 수 있 습 니 다.
  • 등 BIO 작업 이 완료 되면 운영 체제 에서 막 힌 스 레 드 를 깨 우 고[실행 가능 상태]
  • 로 전환 합 니 다.
  • 과[실행 가능 상태]의 차 이 는[차단 상태]의 스 레 드 에 있어 서 그들 이 계속 깨 우지 않 으 면 스케줄 러 는 그들 을 관리 하 는 것 을 고려 하지 않 는 다 는 것 이다
  • .
  • 종료 상태:스 레 드 가 실행 되 었 고 생명 주기 가 끝 났 으 며 다른 상태 로 전환 되 지 않 음 을 나타 낸다
  • 스 레 드 는 자바 API 차원 에서 6 가지 상태 입 니 다.
    在这里插入图片描述
  • NEW 스 레 드 가 생 성 되 었 지만 start()방법 을 호출 하지 않 았 습 니 다
  • RUNNABLE 는 start()방법 을 호출 한 후 자바 API 차원 의
  • 에 주의 하 십시오.
  • RUNNABLE 상 태 는 운영 체제 차원 의[운행 가능 상태],[운행 상태]
  • 를 포함한다.
  • BLOCKED , WAITING , TIMED_WAITING 은 모두 자바 API 차원 에서[차단 상태]에 대한 세분 화
  • TERMINATED 스 레 드 코드 가 실 행 될 때
  • 스 레 드 탱크 는 5 가지 상태 가 있다.
  • 런 닝:새로운 퀘 스 트 를 받 아들 일 수 있 고 대기 열 에 있 는 퀘 스 트 를 처리 할 수 있 습 니 다
  • SHUTDOWN:새 작업 은 받 지 않 지만 대기 열 에 있 는 작업 을 막 을 수 있 습 니 다
  • STOP:새로운 작업 을 받 지 않 고 대기 열 에 있 는 작업 을 처리 하지 않 으 며 작업 을 실행 하고 있 는 스 레 드 를 끊 으 면 바로 그만 두 는 것 입 니 다!
  • TIDYING:모든 작업 이 종료 되 고 작업 스 레 드 도 0 으로 닫 히 기 전 상태
  • TERMINATED:닫 혔 습 니 다.
  • 在这里插入图片描述
    총결산
    이 글 은 여기까지 입 니 다.당신 에 게 도움 을 줄 수 있 기 를 바 랍 니 다.또한 당신 이 우리 의 더 많은 내용 에 관심 을 가 져 주 실 수 있 기 를 바 랍 니 다!

    좋은 웹페이지 즐겨찾기