자바 7: 이해

전환 하 다http://hrps.me/2016/11/22/java-concurrent-phaser/
자바 7 은 Phaser 라 는 유연 한 스 레 드 동기 화 체 제 를 도입 했다.모든 스 레 드 가 도착 한 후에 야 새로운 작업 을 계속 하거나 시작 할 필요 가 있다 면 Phaser 는 좋 은 선택 입 니 다.다음은 코드 와 모든 단계 의 설명 입 니 다.원래 코드 의 해석 이 좋 지 않 은 것 같 아서 나 는 새로 쓴 것 이 더 이해 가 간다.
import java.util.concurrent.Phaser;

/**
 * Description:
 * User: Huang rp
 * Date: 16/11/23
 * Version: 1.0
 */
public class PhaserSamples {

    public static void main(String[] args) throws InterruptedException {
        new PhaserSamples().runTasks();

    }

    //       
    private static final int PHASE_TO_TERMINATE = 2;
    //         
    private static final int INIT_PARTIES = 1;
    //         
    private static final int ADD_PARTIES = 5;
    //            
    private static final int TASKS_PER_PHASER = 10;

    void runTasks() throws InterruptedException {
        final Phaser phaser = new Phaser(INIT_PARTIES) {
            //         ,    ;   PHASE_TO_TERMINATE - 1    ,    (terminal)
            @Override
            protected boolean onAdvance(int phase, int registeredParties) {
                System.out.println(" " + (phase + 1) + "     ");
                return phase == (PHASE_TO_TERMINATE - 1) || registeredParties == 0;
            }
        };
        final Task tasks[] = new Task[ADD_PARTIES];

        System.out.println("      ,    " + INIT_PARTIES + "   ,    " + PHASE_TO_TERMINATE + "   ,     " +
                (ADD_PARTIES % TASKS_PER_PHASER == 0 ? (ADD_PARTIES / TASKS_PER_PHASER) : (ADD_PARTIES / TASKS_PER_PHASER + 1)));
        System.out.println("Main         ,    , " + phaser.getRegisteredParties() + "   ");

        build(tasks, 0, tasks.length, phaser);
        for (int i = 0; i < tasks.length; i++) {
            final Thread thread = new Thread(tasks[i]);
            thread.start();
        }

        phaser.arriveAndDeregister();
        System.out.println("Main    ");
        //        ,         ,       
//        phaser.arriveAndAwaitAdvance();
//        System.out.println("Main         ");
    }

    public static void build(Task[] tasks, int lo, int hi, Phaser ph) {
        if (hi - lo > TASKS_PER_PHASER) {
            for (int i = lo; i < hi; i += TASKS_PER_PHASER) {
                int j = Math.min(i + TASKS_PER_PHASER, hi);
                build(tasks, i, j, new Phaser(ph));
            }
        } else {
            for (int i = lo; i < hi; ++i)
                tasks[i] = new Task(i + 1, ph);
        }
    }


    public static class Task implements Runnable {
        private final int id;
        private final Phaser phaser;

        public Task(int id, Phaser phaser) {
            this.id = id;
            this.phaser = phaser;
            this.phaser.register();
            System.out.println("    " + id + "    , " + phaser.getRegisteredParties() + "   ");
        }

        @Override
        public void run() {
            //        
            while (!phaser.isTerminated()) {
                try {
                    //     ,    
                    Thread.sleep(20 * id + 20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("    " + this.id + "     " + (phaser.getPhase() + 1) + "   ,     "
                        + phaser.getRegisteredParties() + "    ,"
                        + (phaser.getArrivedParties() + 1) + "   ,"
                        + (phaser.getUnarrivedParties() - 1) + "    ");
                //     
                phaser.arriveAndAwaitAdvance();
            }
        }
    }
}

실행 결과
      ,    1   ,    2   ,     1
Main         ,    , 1   
    1    , 2   
    2    , 3   
    3    , 4   
    4    , 5   
    5    , 6   
Main    
    1     1   ,     5    ,1   ,4    
    2     1   ,     5    ,2   ,3    
    3     1   ,     5    ,3   ,2    
    4     1   ,     5    ,4   ,1    
    5     1   ,     5    ,5   ,0    
 1     
    1     2   ,     5    ,1   ,4    
    2     2   ,     5    ,2   ,3    
    3     2   ,     5    ,3   ,2    
    4     2   ,     5    ,4   ,1    
    5     2   ,     5    ,5   ,0    
 2     

몇 가지 주의 사항 이 있 습 니 다. 출석 한 인원 수가 회의장 에 도착 한 인원 수 와 같 으 면 바로 회 의 를 할 것 입 니 다. 그래서 첫 번 째 인원 이 회의장 에 도착 하 는 것 이 마지막 출석 보다 늦 어야 모든 사람 이 회의 에 참석 할 수 있 습 니 다.한 회의장 에서 모든 사람 이 회 의 를 할 수 있 고 같은 phaser 를 모든 task 에 전달 할 수 있 습 니 다.또한 하나의 등급 관 계 를 유지 하고 여러 개의 회의장 을 만들어 같은 회 의 를 진행 하여 모든 참석 자 를 각 회의장 에 평균 적 으로 배정 할 수 있다.출석 한 후 에는 모든 사람 이 회의장 에 도착 하 기 를 기다 리 지 않 고 바로 퇴장 할 수 있 으 며, 출석부 에서 서명 을 지 울 수 있다.다음 회의 가 시작 되 기 전에 다음 회 의 를 기다 리 는 사람 이 있다 면 모든 출석 자 는 다음 회의 에 참석 해 야 한다.모두 가 기다 리 지 않 으 면 회의 가 끝난다.모든 인원 이 지 정 된 수량의 회의 에 참가 한 후에 회의 가 끝났다.
Phaser 가 종료 하 는 두 가지 경로, Phaser 가 유지 하 는 스 레 드 가 실행 되 거나 onAdvance() true 로 돌아 가 는 것 외 에 Phaser 는 하나의 나무 모양 의 등급 관 계 를 유지 할 수 있 습 니 다. 구조 할 때 new Phaser(parentPhaser) Task 의 실행 시간 이 짧 은 장면 (경쟁 이 치열 합 니 다), * TASKSPER_PHASER * * 값 설정 이 적 고 반대로 적당 하 게 증가 합 니 다.
명사 해석:
  • 파티 가 하나의 스 레 드 에 대응 하고 수량 은 register 또는 초기 화 new Phaser(num) 를 통 해 제어 할 수 있 습 니 다
  • arrive 는 파티 의 상태 에 대응 합 니 다. 초기 에는 unarrived 였 습 니 다. 호출 arriveAndAwaitAdvance() 또는 arriveAndDeregister() arrive 상태 에 들 어가 면 getUnarrivedParties() 을 통 해 현재 도착 하지 않 은 수량
  • 을 얻 을 수 있 습 니 다.
  • register 는 하나의 파 티 를 등록 하고 모든 단계 에 등 록 된 파티 가 도착 해 야 다음 단계 에 들 어 갈 수 있 습 니 다
  • phase 단 계 는 모든 등 록 된 파티 가 arrive 되면 PhaseronAdvance() 방법 으로 다음 단계 에 들 어 갈 지 여 부 를 판단 한다
  • .

    좋은 웹페이지 즐겨찾기