5 가지 필수 자바 비동기 호출 동기 화 방법

전재 본 논문 의 주 소 를 밝 혀 주 십시오.https://www.jianshu.com/p/f00aa6f66281
원본 주소:https://gitee.com/sunnymore/asyncToSync
써 니 는 먼저 비동기 와 동기 화 에 대한 이 해 를 말 합 니 다.
동기 호출:호출 자가 호출 과정 에서 결 과 를 되 돌려 주 기 를 계속 기다 리 고 있 습 니 다.비동기 호출:호출 자 는 호출 과정 에서 결 과 를 직접 기다 리 지 않 고 다른 작업 을 수행 합 니 다.결과 반환 형식 은 보통 리 셋 함수 입 니 다.
사실 이들 의 차 이 는 매우 뚜렷 하 다.여기 서도 자세히 말 하지 않 겠 다.우 리 는 자바 가 어떻게 비동기 호출 을 동기 화 하 는 지 에 대해 이야기 하 자.비동기 호출 과정 에서 호출 결 과 를 얻 을 때 까지 계속 차단 해 야 한 다 는 얘 기다.뜸 을 들 이지 않 고 먼저 다섯 가지 방법 을 열거 한 다음 에 일일이 예 를 들 어 설명 한다.
wait 와 notify 방법 을 사용 합 니 다사용 조건 자물쇠
  • Future

  • CountDownlatch 사용 하기
  • CyclicBarrier 를 사용 합 니 다
  • 0.비동기 호출 구성
    우선,demo 를 쓰 려 면 인 프 라 를 먼저 써 야 한다.여기 서 는 주로 비동기 호출 모델 을 구축 해 야 한다.비동기 호출 클래스:
    public class AsyncCall {
    
        private Random random = new Random(System.currentTimeMillis());
    
        private ExecutorService tp = Executors.newSingleThreadExecutor();
    
        //demo1,2,4,5    
        public void call(BaseDemo demo){
    
            new Thread(()->{
                long res = random.nextInt(10);
    
                try {
                    Thread.sleep(res*1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                demo.callback(res);
            }).start();
    
    
        }
    
        //demo3    
        public Future futureCall(){
    
            return tp.submit(()-> {
                long res = random.nextInt(10);
    
                try {
                    Thread.sleep(res*1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return res;
            });
    
        }
    
        public void shutdown(){
    
            tp.shutdown();
    
        }
    
    }
    

    우 리 는 주로 call 방법 에 관심 을 가지 고 있 습 니 다.이 방법 은 demo 인 자 를 받 았 고 스 레 드 를 열 어 스 레 드 에서 구체 적 인 임 무 를 수행 하고 demo 의 callback 방법 으로 리 셋 함수 호출 을 했 습 니 다.여러분 은 이곳 의 반환 결 과 는[0,10)의 긴 정형 이 고 결과 가 얼마 인지 알 게 되 었 습 니 다.이것 은 주로 실험 결 과 를 잘 관찰 하고 비동기 호출 과정 에서 의 처리 시간 을 모 의 하기 위해 서 입 니 다.future Call 과 shutdown 방법,그리고 스 레 드 탱크 tp 는 모두 demo 3 를 이용 하여 Future 를 이용 하여 준비 한 것 입 니 다.demo 의 기본 클래스:
    public abstract class BaseDemo {
    
        protected AsyncCall asyncCall = new AsyncCall();
    
        public abstract void callback(long response);
    
        public void call(){
            System.out.println("    ");
            asyncCall.call(this);
            System.out.println("    ");
        }
    
    }
    

    BaseDemo 는 매우 간단 합 니 다.그 안에 비동기 호출 클래스 의 인 스 턴 스 가 포함 되 어 있 습 니 다.다른 콜 방법 은 비동기 호출 을 시작 하 는 데 사 용 됩 니 다.물론 추상 적 인 방법 인 callback 은 모든 demo 가 실현 해 야 합 니 다.주로 반전 에서 해당 하 는 처 리 를 하여 비동기 호출 동기 화 목적 을 달성 해 야 합 니 다.
    1.wait 와 notify 방법 사용
    이 방법 은 사실 자물쇠 메커니즘 을 이용 하여 코드 를 직접 붙 이 는 것 이다.
    public class Demo1 extends BaseDemo{
    
        private final Object lock = new Object();
    
        @Override
        public void callback(long response) {
            System.out.println("    ");
            System.out.println(response);
            System.out.println("    ");
    
            synchronized (lock) {
                lock.notifyAll();
            }
    
        }
    
        public static void main(String[] args) {
    
            Demo1 demo1 = new Demo1();
    
            demo1.call();
    
            synchronized (demo1.lock){
                try {
                    demo1.lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
            System.out.println("     ");
    
        }
    }
    

    호출 을 시작 한 후 메 인 스 레 드 는 wait 를 이용 하여 차단 하고 리 셋 을 기다 리 는 중 notify 나 notify All 방법 으로 깨 우 는 것 을 볼 수 있 습 니 다.여러분 이 인식 하 는 것 과 마찬가지 로 여기 wait 와 notify 는 대상 의 자 물 쇠 를 먼저 받 아야 합 니 다.메 인 스 레 드 에서 마지막 으로 우 리 는 하나의 내용 을 인쇄 했 습 니 다.이것 도 실험 결 과 를 검증 하 는 데 사 용 됩 니 다.wait 와 notify 가 없 으 면 메 인 스 레 드 내용 은 호출 내용 에 따라 즉시 인쇄 됩 니 다.위의 코드 와 같이 메 인 스 레 드 내용 은 리 셋 함수 호출 이 끝 날 때 까지 기 다 려 야 인쇄 할 수 있 습 니 다.동기 화 작업 을 사용 하지 않 은 상태 에서 결 과 를 인쇄 합 니 다.
        
        
         
        
    1
        
    

    동기 화 작업 을 사용 한 후:
        
        
        
    9
        
         
    

    2.사용 조건 잠 금
    방법 1 의 원리 와 유사 하 다.
    public class Demo2 extends BaseDemo {
    
        private final Lock lock = new ReentrantLock();
        private final Condition con = lock.newCondition();
    
        @Override
        public void callback(long response) {
    
            System.out.println("    ");
            System.out.println(response);
            System.out.println("    ");
            lock.lock();
            try {
                con.signal();
            }finally {
                lock.unlock();
            }
    
        }
    
        public static void main(String[] args) {
    
            Demo2 demo2 = new Demo2();
    
            demo2.call();
    
            demo2.lock.lock();
    
            try {
                demo2.con.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                demo2.lock.unlock();
            }
            System.out.println("     ");
        }
    }
    
    

    기본적으로 방법 과 별 차이 가 없다.다만 여기 서 조건 자 물 쇠 를 사 용 했 을 뿐 이들 의 자물쇠 체 제 는 다소 다르다.
    3. Future
    Future 를 사용 하 는 방법 은 이전 과 달리 우리 가 사용 하 는 비동기 방법 도 다르다.
    public class Demo3{
    
        private AsyncCall asyncCall = new AsyncCall();
    
        public Future call(){
    
            Future future = asyncCall.futureCall();
    
            asyncCall.shutdown();
    
            return future;
    
        }
    
        public static void main(String[] args) {
    
            Demo3 demo3 = new Demo3();
    
            System.out.println("    ");
            Future future = demo3.call();
            System.out.println("    ");
    
            while (!future.isDone() && !future.isCancelled());
    
            try {
                System.out.println(future.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
    
            System.out.println("     ");
    
        }
    }
    

    future Call 방법 을 호출 합 니 다.방법 에 서 는 스 레 드 탱크 tp 가 Callable 을 제출 하고 Future 로 돌아 가 려 고 합 니 다.이 Future 는 우리 demo 3 에서 call 에서 얻 은 것 입 니 다.future 대상 을 얻 으 면 스 레 드 탱크 를 닫 을 수 있 습 니 다.asyncCall 의 shutdown 방법 을 호출 할 수 있 습 니 다.스 레 드 풀 을 닫 는 데 주의 할 점 이 있 습 니 다.asyncCall 의 shutdown 방법 을 돌아 보 겠 습 니 다.
    public void shutdown(){
    
            tp.shutdown();
    
        }
    

    스 레 드 탱크 의 shutdown 방법 만 간단하게 호출 한 것 을 발견 하고 주의 점 을 말 합 니 다.여 기 는 tp 의 shutdown Now 방법 을 사용 하지 않 는 것 이 좋 습 니 다.이 방법 은 스 레 드 에서 실행 중인 작업 을 중단 하려 고 합 니 다.이 방법 을 사용 하면 우리 퓨 처 에 대응 하 는 임무 가 중 단 돼 수행 결 과 를 얻 지 못 할 수도 있다 는 것 이다.그 다음 에 우 리 는 메 인 스 레 드 의 내용 에 관심 을 가지 고 메 인 스 레 드 의 차단 은 우리 스스로 이 루어 집 니 다.future 의 isDone 과 isCanceled 를 통 해 실행 상 태 를 판단 하고 실행 이 완료 되 거나 취 소 될 때 까지 합 니 다.그 후에 우 리 는 get 의 결 과 를 인쇄 합 니 다.
    4.CountDownlatch 사용
    Countdown Latch 를 사용 하 는 것 은 아마도 일상 프로 그래 밍 에서 가장 흔히 볼 수 있 는 것 일 것 입 니 다.또한 상대 적 으로 우아 한 것 같 습 니 다.
    public class Demo4 extends BaseDemo{
    
        private final CountDownLatch countDownLatch = new CountDownLatch(1);
    
        @Override
        public void callback(long response) {
    
            System.out.println("    ");
            System.out.println(response);
            System.out.println("    ");
    
            countDownLatch.countDown();
    
        }
    
        public static void main(String[] args) {
    
            Demo4 demo4 = new Demo4();
    
            demo4.call();
    
            try {
                demo4.countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            System.out.println("     ");
    
        }
    }
    

    평소 사용 하 시 는 것 처럼,이 곳 은 메 인 스 레 드 에서 CountDownlatch 의 await 방법 을 이용 하여 차단 합 니 다.리 셋 에서 countDown 방법 을 이용 하여 다른 스 레 드 await 부분 을 계속 실행 할 수 있 습 니 다.물론,여 기 는 demo 1 과 demo 2 와 마찬가지 로 메 인 스 레 드 에서 막 힌 부분 은 시간 초과 시간 을 설정 할 수 있 습 니 다.시간 초과 후 더 이상 막 히 지 않 을 수 있 습 니 다.
    5.CyclicBarrier 사용
    Cyclic Barrier 의 경우 Count Downlatch 와 유사 합 니 다.
    public class Demo5 extends BaseDemo{
    
        private CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
    
    
        @Override
        public void callback(long response) {
    
            System.out.println("    ");
            System.out.println(response);
            System.out.println("    ");
    
            try {
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
    
        }
    
        public static void main(String[] args) {
    
            Demo5 demo5 = new Demo5();
    
            demo5.call();
    
            try {
                demo5.cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
    
            System.out.println("     ");
    
        }
    }
    

    여러분,Cyclic Barrier 와 Count Downlatch 는 단지 유사 할 뿐,둘 은 어느 정도 차이 가 있 습 니 다.예 를 들 어 하 나 는 덧셈 으로 이해 할 수 있 고 이 숫자 에 추 가 된 후에 함께 운행 할 수 있다.하 나 는 감법 으로 0 으로 줄 여 계속 운행 한다.하 나 는 반복 해서 계산 할 수 있다.하 나 는 안 돼.잠깐 만.잠깐 만.또 Cyclic Barrier 를 사용 할 때 는 두 가 지 를 주의해 야 한다.첫 번 째,초기 화 할 때 매개 변수 숫자 는 2 로 설정 해 야 합 니 다.비동기 호출 은 하나의 스 레 드 이 고 메 인 스 레 드 는 하나의 스 레 드 입 니 다.두 스 레 드 가 모두 await 일 때 만 계속 실 행 됩 니 다.이것 도 Countdown Latch 와 구별 되 는 부분 입 니 다.두 번 째 는 매개 변 수 를 초기 화 하 는 수치 에 관 한 것 입 니 다.여기 demo 와 상 관 없 이 평소에 프로 그래 밍 할 때 조심해 야 합 니 다.만약 에 이 수치 가 크게 설정 되 어 스 레 드 탱크 의 스 레 드 수 보다 크 면 잠 금 을 일 으 키 기 쉽 습 니 다.
    총결산
    종합 하면 이번에 말 해 야 할 몇 가지 방법 이다.사실 모든 방법 은 같은 원리 이다.즉,호출 된 스 레 드 에서 결 과 를 막 고 리 셋 에서 함수 에서 차단 상 태 를 해제 하 는 것 이다.다른 방법 이 있다 면 저 와 토론 해 주세요~
    메 일 박스:[email protected]
    본 고 는 전 재 를 환영 합 니 다.본 고의 주 소 를 밝 혀 주 십시오.https://www.jianshu.com/p/f00aa6f66281

    좋은 웹페이지 즐겨찾기