자바 다 중 스 레 드 빨리 해결 해 줄 게(3)

자물쇠 의 개념
먼저 이 몇 가지 개념 을 이야기 해 보 자.이 야 기 를 나 눌 때 는 아무것도 모 르 고 일 만 해도 소 용이 없다.
공동 잠 금:스 레 드 A 가 이 대상 에 접근 하고 자 물 쇠 를 가 져 오 면 내부 에 카운터 num+1 이 존재 합 니 다.다른 스 레 드 가 이 대상 에 접근 하려 면 줄 을 서서 기다 리 고 있 습 니 다(대기 행렬 의 맨 앞 스 레 드 가 깨 어 날 때 까지 대기 상태 에 있 습 니 다).스 레 드 A 가 자 물 쇠 를 풀 때 까지(num=0)깨 워 야 합 니 다.이 때 깨 어 날 상태 에 있 는 스 레 드 를 깨 워 자 물 쇠 를 가 져 오 는 작업 을 하고 순환 합 니 다.스 레 드 A 가 이 대상 의 자 물 쇠 를 다시 가 져 오 려 고 시도 할 때 이 대상 의 자 물 쇠 는 이미 점용 되 었 는 지 확인 합 니 다.현재 스 레 드 가 자 물 쇠 를 점용 하고 있다 면 바로 자 물 쇠 를 얻 고 줄 에 들 어가 지 않 아 도 됩 니 다.
불공 정 자물쇠:스 레 드 A 가 자 물 쇠 를 풀 면 대상 의 스 레 드 가 자원 경쟁 을 하고 경쟁 에 성공 한 스 레 드 는 이 자 물 쇠 를 얻 으 며 다른 스 레 드 는 계속 잠 을 잔다.
공정 자 물 쇠 는 엄격하게 FIFO 방식 으로 자 물 쇠 를 잠 그 는 경쟁 을 하 는 것 이지 만,불공 정 자 물 쇠 는 무질서 한 자물쇠 경쟁 이다.자 물 쇠 를 방금 풀 어 놓 은 스 레 드 는 어느 정도 자 물 쇠 를 빨리 얻 을 수 있 고,대열 의 스 레 드 는 기다 릴 수 밖 에 없 기 때문에 불공 정 자 물 쇠 는'배 고 픔'의 문제 가 있 을 수 있다.그러나 중복 되 는 잠 금 획득 은 스 레 드 간 의 전환 을 줄 일 수 있 고 공평 한 잠 금 은 엄격 한 스 레 드 전환 이다.그러면 운영 체제 에 미 치 는 영향 이 비교적 크기 때문에 불공평 한 잠 금 의 스루풋 은 공평 한 잠 금 보다 크다.이것 도 JDK 가 불공평 한 잠 금 을 기본 적 인 현실 로 하 는 이유 이다.
비관 적 자물쇠:항상 최 악의 상황 을 가정 하고 데 이 터 를 사용 하려 고 할 때마다 마침 다른 사람 도 데 이 터 를 수정 해 야 한다.모든 것 이 안전 이 최 우선 이기 때문에 자원 을 조작 할 때마다 먼저 자 물 쇠 를 추가 하고 누가 뺏 든 안 뺏 든 간 에 자원 을 독점 한다.자바 에서 synchronized 와 ReentrantLock 등 독점 자 물 쇠 는 비관 적 인 자물쇠 사상의 실현 이다.
낙관 자물쇠:낙관 자물쇠 와 비관 자 물 쇠 는 정반 대 입 니 다.자신 이 자원 을 사용 할 때 뺏 는 사람 이 없다 고 가정 하기 때문에 자 물 쇠 를 채 울 필요 가 없습니다.낙관적 인 자물쇠 의 실현 방안 은 일반적으로 버 전 번호 체제 와 CAS 실현 두 가지 가 있다.이 가능 하 다,~할 수 있다,...
자바 에서 자바.util.concurrent.atomic 패키지 아래 의 원자 변수 류 는 낙관적 인 잠 금 의 실현 방식 인 CAS 를 사용 하여 이 루어 진 것 입 니 다.
2.synchronized 의 사용 방식
장면
구체 적 분류
잠 금 대상
코드 예제
수식 방법
실례 방법
현재 인 스 턴 스 대상
public synchronized void method () { ... }
...
정적 방법
현재 클래스 의 Class 대상
public static synchronized void method () { ... }
수식 코드 블록
부호 블록
()에서 설정 한 대상
synchronized(object) { ... }
3.synchronized 의 실현 원리 열
알 고 싶 어 요.먼저 밑 에 가서 바이트 코드 가 어떤 지 보 세 요.let's go!

  private static Object lock = new Object();
  public static synchronized void testSyn() {
      System.out.println("  ");
  }
  public synchronized void testSyn2() {
      System.out.println("  ");
  }
  public static void testObj() {
      synchronized (lock) {
          System.out.println("  ");
      }
  }
다음 바이트 번호 보기:
图片
synchronized 를 볼 수 있 는 곳 은 Monitorenter 명령 을 사용 합 니 다.모든 대상 은 하나의 Monitor 대상 과 연결 되 어 있 습 니 다.주로 서로 배척 하 는 자원 의 접근 을 제어 하 는 데 사 용 됩 니 다.자 물 쇠 를 추가 하려 면 Monitor 의 승인 을 받 아야 합 니 다.현재 스 레 드 접근 이 있 으 면 신청 한 스 레 드 를 대기 열 에 추가 합 니 다.
작은 매듭
1.synchronized 키 워드 를 방법 에 추가 하 든 대상 에 추가 하 든 그 역할 을 하 는 대상 이 비정 상 이 라면 잠 금 은 대상 입 니 다.synchronized 역할 의 대상 이 정적 방법 이나 클래스 라면,이 잠 금 은 class 대상 에 대한 잠 금 이 며,이 모든 대상 은 같은 잠 금 입 니 다.2.대상 마다 하나의 자물쇠(lock)만 연결 되 어 있 습 니 다.이 자 물 쇠 를 가 진 사람 이 제어 하 는 코드 를 실행 할 수 있 습 니 다.
3.동기 화 를 실현 하 는 것 은 매우 큰 시스템 비용 을 대가 로 하고 심지어 잠 금 을 초래 할 수 있 기 때문에 불필요 한 동기 화 통 제 를 피하 고 내장 synchronized 의 사용 을 피한다.
4.synchronized 는 가능 한 한 범 위 를 통제 해 야 합 니 다.범위 가 너무 넓 어 서 는 안 됩 니 다.그렇지 않 으 면 시스템 성능 을 잃 을 수 있 습 니 다.
4.스 레 드 탱크 는 무엇 입 니까?
스 레 드 탱크 는 대상 이 스 레 드 를 가지 고 있 는 것 이다.예 를 들 어 배 고 파 서 키 우 는 기수 팀 이다.스 레 드 탱크 는 바로 이 팀 으로 모든 기수 가 하나의 스 레 드 이다.
5.왜 스 레 드 탱크 를 사용 합 니까?
만약 에 지금 업 체 에 배달 명세서 가 있 으 면 기수 가 배달 해 야 합 니 다.이때 의 배달 임 무 는 기수 에 게 만 배달 해 주 는데 왜 스 레 드 풀 을 사용 합 니까?
몇 가지 좋 은 점 이 있 습 니 다.첫째,라이 더 의 채용 은 원가 가 있 습 니 다.배달 주문 이 있 으 면 다시 모집 하 는 것 입 니 다.늦 었 습 니 다.평소에 라이 더 를 키 우 는 것 보다 라인 의 생 성과 소각 비용 이 많 습 니 다.
두 번 째 는 한 명의 리스트 가 오 면 한 명의 기수 가 올 수 없다 는 것 이다.그러면 기수 의 수량 을 통제 하기 어렵 고 파이 리스트 에 게 도 큰 압력 이 존재 하기 때문에 전체 기수 팀 의 붕 괴 를 초래 할 수 있다.대응 하 는 것 은 바로 스 레 드 탱크 를 통 해 시스템 안의 스 레 드 수량 을 제어 할 수 있 고 대량의 스 레 드 탱크 가 CPU 자원 을 쟁탈 하여 막 히 는 것 을 효과적으로 피 할 수 있다.
셋째,만약 에 기수 팀 을 키 우 면 기수 관리 에 있어 더욱 좋 은 배달 서 비 스 를 제공 할 수 있다.예 를 들 어 이런 배달 시간 초과,기수 별 치기 등 이다.대비 스 레 드 탱크 는 스 레 드 탱크 가 정시,정기,단일 스 레 드,병발 수 제어 등 기능 을 제공 할 수 있다.
6.다음 유형 도 를 보고 전체적으로 이해 합 니 다.
图片
7.스 레 드 탱크 의 생 성
图片
스 레 드 탱크 에서 주로 사용 하 는 네 가지
고정 수량의 스 레 드 탱크(FixedThreadPool)
정시 스 레 드 탱크(ScheduledThreadPool)
캐 시 가능 스 레 드 탱크(CachedThreadPool)
단선 화 스 레 드 탱크(SingleThreadExecutor)
8.스 레 드 탱크 핵심 매개 변수 설명
우선 스 레 드 탱크 를 어떻게 만 드 는 지 살 펴 보 자.

  public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
      return new ThreadPoolExecutor(nThreads, nThreads,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>(),
                                    threadFactory);
      public ThreadPoolExecutor(int corePoolSize,
                            int maximumPoolSize,
                            long keepAliveTime,
                            TimeUnit unit,
                            BlockingQueue<Runnable> workQueue,
                            ThreadFactory threadFactory,
                            RejectedExecutionHandler handler)
핵심 매개 변수 설명:
图片
아홉,몇 가지 의문점
9.1.스 레 드 가 소각 되 지 않도록 어떻게 보장 합 니까?
핵심 스 레 드 가 워 크 큐 를 기다 리 는 것 을 막 습 니 다.
9.2 임 무 를 제출 하 는 방법 은 몇 가지 가 있 습 니까?
图片
9.3 거부 전략 에는 어떤 것들 이 있 습 니까?
거부 정책(handler)은 스 레 드 탱크 의 스 레 드 수가 최대 스 레 드 수 에 이 르 렀 을 때 거부 정책 을 실행 해 야 합 니 다.거부 정책 은 Rejected Execution Handler 인 터 페 이 스 를 실현 하고 rejected Execution(Runnable r,ThreadPoolExecutor executor)방법 을 실현 해 야 합 니 다.그러나 Executors 프레임 워 크 는 4 가지 거부 전략 을 실현 했다.AbortPolicy(기본 값):작업 을 버 리 고 Rejected Execution Exception 이상 을 던 집 니 다.
4.567914.:호출 스 레 드 로 이 임 무 를 처리 합 니 다.
4.567914.임 무 를 버 리 지만 이상 을 던 지지 않 습 니 다.이 모드 에 맞 춰 사용자 정의 처리 방식 을 사용 할 수 있 습 니 다.
4.567914.대기 열 최초의 미 처리 임 무 를 버 리 고 다시 임 무 를 수행 합 니 다.
9.4 스 레 드 탱크 의 닫 기
스 레 드 풀 을 닫 으 면 shutdown Now 와 shutdown 두 가지 방법 으로 이 루어 집 니 다.CallerRunsPolicy실행 중인 작업 에 대해 모두 interrupt()을 보 내 고 실행 을 중단 하 며 아직 시작 하지 않 은 작업 을 모두 취소 하고 아직 시작 하지 않 은 작업 목록 으로 돌아 갑 니 다.
4.567914.우리 가 shutdown 을 호출 하면 스 레 드 탱크 는 새로운 임 무 를 받 지 않 지만 이미 제출 하거나 실행 중인 임 무 를 강제로 중지 하지 않 습 니 다.
9.5 스 레 드 풀 초기 화 시 스 레 드 수 선택
작업 이 IO 밀집 형 이 라면 일반 스 레 드 수 는 CPU 수 이상 을 2 배 이상 설정 해 CPU 자원 을 최대한 활용 해 야 한다.
작업 이 CPU 밀집 형 이 라면 일반 스 레 드 수량 은 CPU 수 에 1 을 더 하면 되 고 더 많은 스 레 드 수도 컨 텍스트 전환 만 증가 할 수 있 으 며 CPU 이 용 률 을 증가 시 킬 수 없습니다.
구체 적 인 문 제 를 구체 적 으로 분석 하 다.
총화
스 레 드 탱크 는 프로젝트 에서 자주 사용 되 는 것 으로 스 레 드 탱크 의 응용 장면 과 구조 함 수 를 이해 하고 스 레 드 탱크 를 정확하게 사용 해 야 한다.
이 글 은 여기까지 입 니 다.당신 에 게 도움 을 줄 수 있 기 를 바 랍 니 다.또한 당신 이 우리 의 더 많은 내용 에 관심 을 가 져 주 실 수 있 기 를 바 랍 니 다!

좋은 웹페이지 즐겨찾기