jdk 에 random 이 4 개 있 는 거 알 아 요?

8579 단어 jdkrandom난수
jdk 8 부터 얘 기 하 자.주로 네 개의 난수 생 성기 이다.신마네 개 있어 요?
그 다음 에 우 리 는 이런 몇 가지 사용 장면 을 간단하게 말 해서 그 중의 미세한 차 이 를 파악 하고 api 디자이너 의 심혈 을 기울 인 다.
java.util.Randomjava.util.concurrent.ThreadLocalRandomjava.security.SecureRandomjava.util.SplittableRandom
Random
가장 많이 쓰 이 는 것 은 랜 덤 이다.
가짜 랜 덤 수 를 만 드 는 데 사용 되 며,기본적으로 48 비트 피 드,선형 동 여 공식 을 사용 하여 수정 합 니 다.우 리 는 구조 기 를 통 해 초기 seed 에 들 어가 거나 setSeed 를 통 해 리 셋(동기 화)할 수 있 습 니 다.기본 seed 는 시스템 시간의 나 초 수 입 니 다.정말 큽 니 다!
만약 두 개(여러 개)가 다른 Random 실례 를 사용 하고 같은 seed 를 사용 하 며 같은 순서에 따라 같은 방법 을 호출한다 면,그들 이 얻 은 숫자 서열 도 같다.이것 은 그다지 랜 덤 해 보이 지 않 는 다. 이러한 디자인 전략 은 장점 도 있 고 단점 도 있다.장점 은'같은 seed'가 생 성 된 서열 이 일치 하고 과정 을 거 슬러 올 라 갈 수 있 고 검증 할 수 있 도록 하 는 것 이다(플랫폼 과 상 관 없 이 운영 시기 와 무관 하 다).단점 은 이런 일치 성 이'예측 가능'한 위험 을 잠재 적 으로 도입 한 다 는 것 이다.
Random 의 인 스 턴 스 는 스 레 드 가 안전 합 니 다. 그러나 크로스 스 레 드 와 같은 자바 util.Random 인 스 턴 스 를 동시에 사용 하면 경쟁 을 만 나 성능 이 약간 떨 어 질 수 있 습 니 다(nextX 방법 에서 seed 에 값 을 부여 할 때 CAS 를 사 용 했 습 니 다.테스트 결과 성능 손실 이 적은 것 으로 나 타 났 습 니 다).다 중 스 레 드 디자인 에서 ThreadLocalRandom 을 사용 하 는 것 을 고려 하 십시오.동시에 우 리 는 병발 환경 에서 도 여러 개의 랜 덤 실례 를 굳이 사용 할 필요 가 없다.
Random 인 스 턴 스 는 암호 화 보안 이 없습니다. 반면 보안 에 민감 한 프로그램 이 사용 할 수 있 도록 SecureRandom 을 사용 하 십시오.
Random 은 가장 자주 사용 하 는 난수 생 성 클래스 로 대부분의 장면 에 적용 된다.

Random random = new Random(100);System.out.println(random.nextInt(10) + "," + random.nextInt(30) + "," + random.nextInt(50));random = new Random(100);System.out.println(random.nextInt(10) + "," + random.nextInt(30) + "," + random.nextInt(50));random = new Random(100);System.out.println(random.nextInt(10) + "," + random.nextInt(30) + "," + random.nextInt(50));
위 세 개의 서로 다른 random 인 스 턴 스 는 같은 seed 를 사용 합 니 다.호출 과정 과 마찬가지 로 그 중에서 발생 하 는 난수 서열 도 완전히 같다.여러 번 의 실행 결과 도 완전히 일치 합 니 다.쉽게 말 하면 초기 seed 와 같 으 면 인 스 턴 스 가 다 르 더 라 도 여러 번 실행 한 결 과 는 일치 합 니 다.이 현상 은 위 에서 말 한 것 과 일치한다.
Random 구조 기 에서 seed 를 지정 하지 않 고 기본 시스템 시간 나 초 수 를 주도 변수 로 사용 하면 세 개의 random 인 스 턴 스 가 실 행 된 결 과 는 다 릅 니 다.여러 차례 실 행 된 결과 도 달 랐 다.이 를 통 해 seed 가 랜 덤 성 을 가지 고 있 는 지 여 부 는 어느 정도 랜 덤 이 결 과 를 낳 는 랜 덤 성 을 결정 한 다 는 것 을 알 수 있다.
따라서 분포 식 또는 다 중 스 레 드 환경 에서 랜 덤 인 스 턴 스 가 코드 가 일치 하 는 tasks 스 레 드 에 있 으 면 이러한 분포 식 프로 세 스 나 스 레 드 가 생산 되 는 시퀀스 값 이 같 을 수 있 습 니 다.JDK 7 이 포크 조 인 트 를 도입 하면 서 스 레 드 로 컬 랜 덤 클래스 도 도입 한 것 이다.
ThreadLocalRandom
이 종류의 역할 은 무 작위 생 성 기 를 현재 스 레 드 로 격 리 시 킵 니 다.이러한 계승 은 java.util.Random 에서 이 루어 집 니 다.Math 클래스 에서 사용 하 는 전역 Random 생 성기 와 마찬가지 로 ThreadLocalRandom 은 내부 에서 생 성 된 피 드 를 사용 하여 초기 화 합 니 다.그렇지 않 으 면 수정 할 수 없습니다.
동시 다발 프로그램 에서 ThreadLocal Random 을 사용 하면 비용 과 경쟁 이 더 적다.여러 작업(예 를 들 어 모든 ForkJointask)이 온라인 프로 세 스 풀 에서 무 작위 수 를 병행 할 때 ThreadLocalRandom 은 특히 적합 합 니 다.
여러 스 레 드 에서 ThreadLocal Random 인 스 턴 스 를 공유 해 서 는 안 된다 는 것 을 명심 하 세 요.
ThreadLocalRandom 초기 화 는 private 이기 때문에 구조 기 를 통 해 seed 를 설정 할 수 없습니다.또한 setSeed 방법 도 지원 되 지 않 고 재 작성 되 었 습 니 다(이상 던 지기).기본 적 인 상황 에서 모든 ThreadLocalRandom 인 스 턴 스 의 seed 주도 변 수 는 시스템 시간(나 초)입 니 다.

private static long initialSeed() {    String sec = VM.getSavedProperty("java.util.secureRandomSeed");    if (Boolean.parseBoolean(sec)) {        byte[] seedBytes = java.security.SecureRandom.getSeed(8);        long s = (long)(seedBytes[0]) & 0xffL;        for (int i = 1; i < 8; ++i)            s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);        return s;    }    return (mix64(System.currentTimeMillis()) ^            mix64(System.nanoTime()));}
seed 초기 화 에 따라 JVM 시작 매개 변 수 를 통 해"-Dja.util.secureRandomSeed=true"를 추가 할 수 있 습 니 다.이때 초기 seed 변 수 는 시스템 시간 이 아니 라 SecureRandom 류 에서 무 작위 인 자 를 생 성하 여 ThreadLoalRandom 의 초기 seed 로 사용 할 수 있 습 니 다.
정말 복잡 하 다.
원본 코드 에서 저 는 Thread-ID 가 변수 로 seed 를 만 드 는 것 을 보지 못 했 고 nextX 방법 에서 난수 생 성 알고리즘 도 일치 합 니 다.이 는 여러 스 레 드 의 초기 ThreadLocalRandom 시간 이 완전히 일치 하면 호출 방법 과 과정 이 같은 상황 에서 발생 하 는 무 작위 서열 도 같다 는 것 을 의미한다.어느 정도'-Djva.util.secureRandom=true'는 이 문 제 를 피 할 수 있다.
ThreadLocalRandom 은 내부 데이터 저장 등 을 지원 하기 위해 ThreadLocal 을 사용 하지 않 고 UnSafe 를 사용 하여 현재 Thread 대상 이 seed 속성의 메모리 주 소 를 참조 하고 데 이 터 를 조작 합 니 다.저 는 SUN 의 이런 교묘 한 방법 에 탄복 합 니 다.
SecureRandom
또한 랜 덤 에서 계승 되 었 다.이 종 류 는 암호 화 강 랜 덤 생 성기(RNG)를 제공 하고 암호 화 강 랜 덤 수 는 FIPS 140-2'암호 화 모듈 의 안전 요구'에 최소한 부합 한다.이 밖 에 SecureRandom 은 불확실 성 출력 을 만들어 야 한다.따라서 SecureRandom 대상 에 게 전달 되 는 모든 피 드 재 료 는 예측 할 수 없 으 며 모든 SecureRandom 출력 서열 은 암호 화 강 도 를 가 져 야 합 니 다.(관문
SecureRandom 은 기본적으로 두 가지 RNG 암호 화 알고리즘 을 지원 합 니 다.
"SHA1PRNG"알고리즘 제공 자 sun.security.provider.SecureRandom
"NativePRNG"공급 자 sun.security.provider.NativePRNG
기본적으로'SHA1PRNG',즉 썬 이 제공 한 실현 이다.그 밖 에 통과 할 수 있다.
“-Djava.security=file:/dev/urandom”
(추천)혹은
“-Djava.security=file:/dev/random”
Liux 로 컬 의 랜 덤 알고리즘 을 지정 합 니 다.
즉 NativePRNG;
그 중에서'/dev/random'과'/dev/urandom'은 서로 다른 유 닉 스-*플랫폼 에서 실현 되 는 것 이 다 르 고 성능 도 차이 가 있 으 므 로'/dev/urandom'을 사용 하 는 것 을 권장 합 니 다.
/dev/random 의 복사 본 은/dev/urandom("unlocked",막 히 지 않 는 난수 발생 기)입 니 다.엔트로피 풀 의 데 이 터 를 반복 해서 사용 하여 가짜 랜 덤 데 이 터 를 만 듭 니 다.이것 은/dev/urandom 의 읽 기 동작 에 차단 이 되 지 않 지만 출력 엔트로피 는/dev/random 보다 작 을 수 있 음 을 나타 낸다.강도 가 낮은 암 호 를 만 드 는 가짜 난수 생 성기 로 서 강도 가 높 은 장기 암 호 를 만 드 는 것 을 권장 하지 않 습 니 다.
알고리즘 의 내부 실현 은 비교적 복잡 하 다.본인 테스트 는 사실 성능 이 그다지 좋 지 않 습 니 다(JDK 8 환경).SecureRandom 도 스 레 드 가 안전 합 니 다.
출력 결과 에서 분석 하면 SecureRandom 의 초기 seed 를 지정 하 든 말 든 하나의 인 스 턴 스 가 여러 번 실 행 된 결과 도 완전히 다르다.여러 개의 서로 다른 SecureRandom 인 스 턴 스 는 seed 를 지정 하 든 말 든 같은 초기 seed 를 지정 하 더 라 도 동시에 실행 되 는 결 과 는 완전히 다르다.
SecureRandom 은 Random 에서 계승 되 었 으 나 nextX 방법 중의 바 텀 방법 에 대한 재 작성 커버 는 Random 의 CAS 를 바탕 으로 하고 SecureRandom 의 바 텀 방법 은 동기 화 되 어 병발 환경 에서 Random 보다 성능 이 떨 어 졌 다.
SplittableRandom
JDK 8 에 추 가 된 API 는 주로 Fork/join 형식의 크로스 스 레 드 작업 에 적 용 됩 니 다.그것 은 자바 util.Random 류 를 계승 하지 않 았 다.
같은 seed 의 다른 Splittable Random 인 스 턴 스 나 같은 Splittable Random 을 가지 고 있 으 며,여러 번 실행 한 결 과 는 일치 합 니 다.이것 은 랜 덤 과 일치한다.
비 스 레 드 가 안전 하여 동시에 사용 할 수 없습니다.(오 류 는 없 지만 동시 다발 시 여러 스 레 드 가 동시에 같은 임 의 수 를 얻 을 수 있 습 니 다)
ThreadLocalRandom 과 같이"-Djva.util.secureRandom=true"매개 변 수 를 지원 하지만 기본 구조 기 를 사용 할 때 만 SecureRandom 을 사용 하여 초기 seed 를 보조 적 으로 생 성 합 니 다.즉,초기 seed 를 지정 하지 않 을 때 같은 Splittable Random 인 스 턴 스 가 여러 번 실행 되 거나 다른 인 스 턴 스 가 실 행 됩 니 다.결 과 는 다 릅 니 다.
새로운 인 스 턴 스 를 구성 하고 되 돌려 주 는 split()방법 이 있 습 니 다.이 인 스 턴 스 는 가 변 적 이지 않 은 상 태 를 공유 합 니 다.split 에서 발생 하 는 새로운 Splittable Random 인 스 턴 스 는 원래 의 인 스 턴 스 와 내부 데이터 의 병행 경쟁 이 존재 하지 않 고 원래 의 인 스 턴 스 의 임 의 수 생 성 서열 을 교체 하거나 연장 하지 않 습 니 다(즉,두 인 스 턴 스 가 임 의 서열 을 생산 하 는 일치 성 은 원래 의 인 스 턴 스 와 관계 가 없 으 며 통계 값 차원 에서 더욱 가 깝 습 니 다).그러나 코드 가 일치 하 는 상황 에서 여러 번 실 행 됩 니 다.무 작위 배열 의 결 과 는 항상 일치 합 니 다.(초기 seed 가 기본 값 이 아 닌 지정 한 것 이 라면)이 점 은 Random,ThreadLocalRandom 과 같 습 니 다.

public SplittableRandom split() {    return new SplittableRandom(nextLong(), mixGamma(nextSeed()));}
샘플 코드.

System.out.println("   ");SplittableRandom random = new SplittableRandom(100);Thread thread = new Thread(new Runnable() {    @Override    public void run() {        SplittableRandom _random = random.split();        for (int i=0; i < 5; i++) {            System.out.println("---" + _random.nextInt(100));        }    }});thread.start();thread.join();for (int i=0; i < 5; i++) {    System.out.println("+++" + random.nextInt(100));}System.out.println("   ");SplittableRandom _random = new SplittableRandom(100);for (int i=0; i < 10; i++) {    System.out.println("..." + _random.nextInt(100));}
실행 결과.
1 단-71-85-10-60-98++44++87++77++67++72 2 단.
실행 결 과 를 보면 split 에서 발생 하 는 random 인 스 턴 스 는 원래 의 인 스 턴 스 실행 결과 와 비슷 한 점 이 없습니다.그러나 Splittable Random 인 스 턴 스(split 를 실 행 했 든 안 했 든)에 따라 난수 서열 이 일치 합 니 다.
성능 검사
간략 분석,기준:100000 난수,단일 라인
1.Random:2 밀리초
2,ThreadLocalRandom:1 밀리초
3、 SecureRandom
1)기본 알고리즘,즉 SHAR1PRNG:80 밀리초 정도.
2)NativePRNG:90 밀리초 정도.
4,SplittableRandom:1 밀리초
End
평소에 Random 을 사용 하거나 대부분 사용 할 때 문제 가 없 으 며 스 레 드 도 안전 합 니 다.Splittable Random 은 내부 에서 사용 하 는 클래스 로 응용 이 적 고 Public 라 도 옆문 을 숨 길 수 없습니다.ThreadLocalRandom 은 높 은 병발 환경 에서 약간의 시간 을 절약 하고 성능 을 추구 하기 위 한 응용 추천 으로 사용 된다.그리고 안전 수요 가 있 는 사람 에 게 는 좀 더 무 작위 적 인 것 을 원 합 니 다.SecureRandom 을 사용 하 는 것 이 좋 습 니 다.
jdk 에 이렇게 많은 랜 덤 생 성기 가 있다 니.실컷 먹 었 습 니까?나 어차피 무릎 꿇 었 으 니까
jdk 에 관 한 이 글 은 4 개의 random 에 관 한 글 이 여기까지 소개 되 었 습 니 다.더 많은 관련 jdk 는 4 개의 random 내용 이 있 습 니 다.우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!

좋은 웹페이지 즐겨찾기