Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
f9ad02d9
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
f9ad02d9
编写于
8月 29, 2013
作者:
L
lana
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
26838e9b
5a6445a4
变更
127
显示空白变更内容
内联
并排
Showing
127 changed file
with
6440 addition
and
954 deletion
+6440
-954
make/com/sun/security/auth/FILES_java.gmk
make/com/sun/security/auth/FILES_java.gmk
+1
-3
makefiles/Profiles.gmk
makefiles/Profiles.gmk
+4
-4
src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java
src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java
+1
-0
src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java
src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java
+0
-5
src/share/back/SDE.c
src/share/back/SDE.c
+6
-0
src/share/classes/com/sun/tools/attach/VirtualMachine.java
src/share/classes/com/sun/tools/attach/VirtualMachine.java
+50
-31
src/share/classes/java/io/BufferedInputStream.java
src/share/classes/java/io/BufferedInputStream.java
+15
-4
src/share/classes/java/lang/AbstractStringBuilder.java
src/share/classes/java/lang/AbstractStringBuilder.java
+2
-2
src/share/classes/java/lang/Class.java
src/share/classes/java/lang/Class.java
+10
-2
src/share/classes/java/lang/Math.java
src/share/classes/java/lang/Math.java
+3
-8
src/share/classes/java/lang/ProcessBuilder.java
src/share/classes/java/lang/ProcessBuilder.java
+2
-3
src/share/classes/java/lang/StrictMath.java
src/share/classes/java/lang/StrictMath.java
+3
-8
src/share/classes/java/math/BigDecimal.java
src/share/classes/java/math/BigDecimal.java
+18
-14
src/share/classes/java/math/BigInteger.java
src/share/classes/java/math/BigInteger.java
+1
-1
src/share/classes/java/rmi/server/RMISocketFactory.java
src/share/classes/java/rmi/server/RMISocketFactory.java
+4
-4
src/share/classes/java/util/Collections.java
src/share/classes/java/util/Collections.java
+51
-6
src/share/classes/java/util/ComparableTimSort.java
src/share/classes/java/util/ComparableTimSort.java
+2
-1
src/share/classes/java/util/Comparator.java
src/share/classes/java/util/Comparator.java
+16
-16
src/share/classes/java/util/Random.java
src/share/classes/java/util/Random.java
+646
-54
src/share/classes/java/util/SplittableRandom.java
src/share/classes/java/util/SplittableRandom.java
+1002
-0
src/share/classes/java/util/TimSort.java
src/share/classes/java/util/TimSort.java
+2
-1
src/share/classes/java/util/TreeMap.java
src/share/classes/java/util/TreeMap.java
+21
-0
src/share/classes/java/util/concurrent/ThreadLocalRandom.java
...share/classes/java/util/concurrent/ThreadLocalRandom.java
+741
-130
src/share/classes/java/util/concurrent/locks/StampedLock.java
...share/classes/java/util/concurrent/locks/StampedLock.java
+198
-166
src/share/classes/java/util/jar/JarVerifier.java
src/share/classes/java/util/jar/JarVerifier.java
+3
-1
src/share/classes/java/util/logging/Logger.java
src/share/classes/java/util/logging/Logger.java
+9
-7
src/share/classes/java/util/regex/Pattern.java
src/share/classes/java/util/regex/Pattern.java
+3
-5
src/share/classes/java/util/stream/Collectors.java
src/share/classes/java/util/stream/Collectors.java
+19
-21
src/share/classes/java/util/stream/DistinctOps.java
src/share/classes/java/util/stream/DistinctOps.java
+2
-2
src/share/classes/java/util/stream/DoublePipeline.java
src/share/classes/java/util/stream/DoublePipeline.java
+7
-8
src/share/classes/java/util/stream/IntPipeline.java
src/share/classes/java/util/stream/IntPipeline.java
+9
-12
src/share/classes/java/util/stream/LongPipeline.java
src/share/classes/java/util/stream/LongPipeline.java
+8
-11
src/share/classes/java/util/stream/ReferencePipeline.java
src/share/classes/java/util/stream/ReferencePipeline.java
+12
-14
src/share/classes/java/util/stream/Sink.java
src/share/classes/java/util/stream/Sink.java
+12
-16
src/share/classes/java/util/stream/SliceOps.java
src/share/classes/java/util/stream/SliceOps.java
+15
-10
src/share/classes/java/util/stream/SortedOps.java
src/share/classes/java/util/stream/SortedOps.java
+17
-17
src/share/classes/java/util/zip/ZipOutputStream.java
src/share/classes/java/util/zip/ZipOutputStream.java
+10
-0
src/share/classes/javax/net/ssl/SNIHostName.java
src/share/classes/javax/net/ssl/SNIHostName.java
+2
-1
src/share/classes/javax/net/ssl/X509KeyManager.java
src/share/classes/javax/net/ssl/X509KeyManager.java
+2
-2
src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java
...asses/javax/security/auth/kerberos/KerberosPrincipal.java
+4
-10
src/share/classes/sun/nio/ch/AbstractPollSelectorImpl.java
src/share/classes/sun/nio/ch/AbstractPollSelectorImpl.java
+0
-5
src/share/classes/sun/nio/ch/DatagramChannelImpl.java
src/share/classes/sun/nio/ch/DatagramChannelImpl.java
+1
-1
src/share/classes/sun/nio/ch/FileChannelImpl.java
src/share/classes/sun/nio/ch/FileChannelImpl.java
+1
-1
src/share/classes/sun/nio/ch/IOUtil.java
src/share/classes/sun/nio/ch/IOUtil.java
+16
-2
src/share/classes/sun/nio/ch/Net.java
src/share/classes/sun/nio/ch/Net.java
+1
-1
src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
+1
-1
src/share/classes/sun/nio/ch/SocketChannelImpl.java
src/share/classes/sun/nio/ch/SocketChannelImpl.java
+1
-1
src/share/classes/sun/nio/ch/Util.java
src/share/classes/sun/nio/ch/Util.java
+0
-26
src/share/classes/sun/tools/jconsole/ConnectDialog.java
src/share/classes/sun/tools/jconsole/ConnectDialog.java
+7
-2
src/share/classes/sun/tools/jconsole/JConsole.java
src/share/classes/sun/tools/jconsole/JConsole.java
+4
-0
src/share/classes/sun/tools/jconsole/Messages.java
src/share/classes/sun/tools/jconsole/Messages.java
+2
-2
src/share/classes/sun/tools/jconsole/Plotter.java
src/share/classes/sun/tools/jconsole/Plotter.java
+8
-1
src/share/classes/sun/tools/jconsole/ThreadTab.java
src/share/classes/sun/tools/jconsole/ThreadTab.java
+2
-0
src/share/classes/sun/tools/jconsole/VMPanel.java
src/share/classes/sun/tools/jconsole/VMPanel.java
+5
-3
src/share/classes/sun/tools/jconsole/resources/messages.properties
.../classes/sun/tools/jconsole/resources/messages.properties
+1
-1
src/share/classes/sun/tools/jconsole/resources/messages_ja.properties
...asses/sun/tools/jconsole/resources/messages_ja.properties
+0
-1
src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties
...es/sun/tools/jconsole/resources/messages_zh_CN.properties
+0
-1
src/share/lib/security/java.security-linux
src/share/lib/security/java.security-linux
+2
-0
src/share/lib/security/java.security-macosx
src/share/lib/security/java.security-macosx
+2
-0
src/share/lib/security/java.security-solaris
src/share/lib/security/java.security-solaris
+2
-0
src/share/lib/security/java.security-windows
src/share/lib/security/java.security-windows
+2
-0
src/share/native/common/check_code.c
src/share/native/common/check_code.c
+6
-0
src/solaris/classes/sun/nio/ch/DatagramDispatcher.java
src/solaris/classes/sun/nio/ch/DatagramDispatcher.java
+1
-1
src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java
src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java
+4
-0
src/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java
src/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java
+0
-5
src/solaris/classes/sun/nio/ch/EPoll.java
src/solaris/classes/sun/nio/ch/EPoll.java
+1
-1
src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java
src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java
+1
-0
src/solaris/classes/sun/nio/ch/EPollPort.java
src/solaris/classes/sun/nio/ch/EPollPort.java
+1
-1
src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java
src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java
+0
-4
src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java
src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java
+1
-1
src/solaris/classes/sun/nio/ch/InheritedChannel.java
src/solaris/classes/sun/nio/ch/InheritedChannel.java
+1
-1
src/solaris/classes/sun/nio/ch/KQueue.java
src/solaris/classes/sun/nio/ch/KQueue.java
+1
-1
src/solaris/classes/sun/nio/ch/KQueuePort.java
src/solaris/classes/sun/nio/ch/KQueuePort.java
+1
-1
src/solaris/classes/sun/nio/ch/NativeThread.java
src/solaris/classes/sun/nio/ch/NativeThread.java
+1
-1
src/solaris/classes/sun/nio/ch/PollArrayWrapper.java
src/solaris/classes/sun/nio/ch/PollArrayWrapper.java
+3
-0
src/solaris/classes/sun/nio/ch/SinkChannelImpl.java
src/solaris/classes/sun/nio/ch/SinkChannelImpl.java
+1
-7
src/solaris/classes/sun/nio/ch/SolarisEventPort.java
src/solaris/classes/sun/nio/ch/SolarisEventPort.java
+1
-1
src/solaris/classes/sun/nio/ch/SourceChannelImpl.java
src/solaris/classes/sun/nio/ch/SourceChannelImpl.java
+1
-7
src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java
...s/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java
+1
-1
src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java
...classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java
+1
-1
src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java
src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java
+1
-1
src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java
...solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java
+1
-1
src/solaris/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java
...olaris/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java
+1
-1
src/windows/classes/sun/nio/ch/DatagramDispatcher.java
src/windows/classes/sun/nio/ch/DatagramDispatcher.java
+1
-1
src/windows/classes/sun/nio/ch/FileDispatcherImpl.java
src/windows/classes/sun/nio/ch/FileDispatcherImpl.java
+1
-1
src/windows/classes/sun/nio/ch/FileKey.java
src/windows/classes/sun/nio/ch/FileKey.java
+1
-0
src/windows/classes/sun/nio/ch/Iocp.java
src/windows/classes/sun/nio/ch/Iocp.java
+1
-1
src/windows/classes/sun/nio/ch/PipeImpl.java
src/windows/classes/sun/nio/ch/PipeImpl.java
+0
-1
src/windows/classes/sun/nio/ch/SocketDispatcher.java
src/windows/classes/sun/nio/ch/SocketDispatcher.java
+1
-1
src/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java
...lasses/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java
+1
-1
src/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java
...un/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java
+1
-1
src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java
...sses/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java
+1
-1
src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java
src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java
+1
-1
test/ProblemList.txt
test/ProblemList.txt
+1
-7
test/TEST.ROOT
test/TEST.ROOT
+3
-0
test/TEST.groups
test/TEST.groups
+214
-0
test/java/io/BufferedInputStream/LargeCopyWithMark.java
test/java/io/BufferedInputStream/LargeCopyWithMark.java
+117
-0
test/java/io/File/MaxPathLength.java
test/java/io/File/MaxPathLength.java
+4
-5
test/java/io/pathNames/General.java
test/java/io/pathNames/General.java
+6
-5
test/java/lang/SecurityManager/CheckPackageAccess.java
test/java/lang/SecurityManager/CheckPackageAccess.java
+2
-1
test/java/lang/annotation/AnnotationType/AnnotationTypeDeadlockTest.java
...annotation/AnnotationType/AnnotationTypeDeadlockTest.java
+19
-23
test/java/lang/annotation/TypeAnnotationReflection.java
test/java/lang/annotation/TypeAnnotationReflection.java
+2
-2
test/java/lang/annotation/typeAnnotations/GetAnnotatedSuperclass.java
...ng/annotation/typeAnnotations/GetAnnotatedSuperclass.java
+56
-0
test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java
...va/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java
+4
-4
test/java/math/BigDecimal/IntegralDivisionTests.java
test/java/math/BigDecimal/IntegralDivisionTests.java
+4
-1
test/java/nio/file/WatchService/SensitivityModifier.java
test/java/nio/file/WatchService/SensitivityModifier.java
+53
-47
test/java/util/Arrays/TimSortStackSize.java
test/java/util/Arrays/TimSortStackSize.java
+116
-0
test/java/util/Collections/Wrappers.java
test/java/util/Collections/Wrappers.java
+146
-0
test/java/util/Comparator/BasicTest.java
test/java/util/Comparator/BasicTest.java
+21
-21
test/java/util/Map/EntryComparators.java
test/java/util/Map/EntryComparators.java
+2
-2
test/java/util/Random/RandomStreamTest.java
test/java/util/Random/RandomStreamTest.java
+0
-27
test/java/util/Random/RandomTest.java
test/java/util/Random/RandomTest.java
+430
-0
test/java/util/SplittableRandom/SplittableRandomTest.java
test/java/util/SplittableRandom/SplittableRandomTest.java
+560
-0
test/java/util/concurrent/ThreadLocalRandom/ThreadLocalRandomTest.java
...l/concurrent/ThreadLocalRandom/ThreadLocalRandomTest.java
+559
-0
test/java/util/concurrent/locks/StampedLock/ReadersUnlockAfterWriteUnlock.java
...rent/locks/StampedLock/ReadersUnlockAfterWriteUnlock.java
+88
-0
test/java/util/function/BinaryOperator/BasicTest.java
test/java/util/function/BinaryOperator/BasicTest.java
+7
-7
test/java/util/logging/Logger/getLogger/TestLogger.java
test/java/util/logging/Logger/getLogger/TestLogger.java
+98
-0
test/java/util/logging/Logger/getLogger/testlogger/MyResource.java
.../util/logging/Logger/getLogger/testlogger/MyResource.java
+25
-19
test/java/util/regex/PatternTest.java
test/java/util/regex/PatternTest.java
+147
-0
test/java/util/regex/RegExTest.java
test/java/util/regex/RegExTest.java
+11
-1
test/java/util/stream/test/org/openjdk/tests/java/util/SplittableRandomTest.java
...est/org/openjdk/tests/java/util/SplittableRandomTest.java
+367
-0
test/java/util/zip/TestExtraTime.java
test/java/util/zip/TestExtraTime.java
+43
-20
test/sun/security/krb5/auto/KPEquals.java
test/sun/security/krb5/auto/KPEquals.java
+55
-0
test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java
...rity/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java
+88
-34
test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java
...curity/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java
+85
-32
test/sun/security/ssl/templates/SSLSocketTemplate.java
test/sun/security/ssl/templates/SSLSocketTemplate.java
+1
-1
test/sun/security/tools/jarsigner/jvindex.sh
test/sun/security/tools/jarsigner/jvindex.sh
+76
-0
未找到文件。
make/com/sun/security/auth/FILES_java.gmk
浏览文件 @
f9ad02d9
#
# Copyright (c) 2000, 20
06
, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2000, 20
13
, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
...
...
@@ -43,8 +43,6 @@ FILES_java = \
com/sun/security/auth/UserPrincipal.java \
com/sun/security/auth/LdapPrincipal.java \
com/sun/security/auth/PolicyFile.java \
com/sun/security/auth/SubjectCodeSource.java \
com/sun/security/auth/PolicyParser.java \
com/sun/security/auth/PrincipalComparator.java \
com/sun/security/auth/callback/TextCallbackHandler.java \
com/sun/security/auth/callback/DialogCallbackHandler.java
makefiles/Profiles.gmk
浏览文件 @
f9ad02d9
...
...
@@ -65,10 +65,6 @@ PROFILE_2_JARS := \
$(if $(PROFILE_2_JRE_JAR_FILES), $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(PROFILE_2_JRE_JAR_FILES))) \
$(PROFILE_1_JARS)
ifneq ($(ENABLE_JFR), true)
PROFILE_3_JRE_JAR_FILES := $(filter-out jfr.jar, $(PROFILE_3_JRE_JAR_FILES))
endif
PROFILE_3_JARS := \
$(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(PROFILE_3_JRE_JAR_FILES)) \
$(PROFILE_2_JARS)
...
...
@@ -77,6 +73,10 @@ ifdef OPENJDK
FULL_JRE_JAR_FILES := $(filter-out alt-rt.jar, $(FULL_JRE_JAR_FILES))
endif
ifneq ($(ENABLE_JFR), true)
FULL_JRE_JAR_FILES := $(filter-out jfr.jar, $(FULL_JRE_JAR_FILES))
endif
FULL_JRE_JARS := \
$(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(FULL_JRE_JAR_FILES)) \
$(PROFILE_3_JARS)
...
...
src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java
浏览文件 @
f9ad02d9
...
...
@@ -87,6 +87,7 @@ class KQueueArrayWrapper {
private
int
incomingInterruptFD
;
static
{
IOUtil
.
load
();
initStructSizes
();
String
datamodel
=
java
.
security
.
AccessController
.
doPrivileged
(
new
sun
.
security
.
action
.
GetPropertyAction
(
"sun.arch.data.model"
)
...
...
src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -246,9 +246,4 @@ class KQueueSelectorImpl
}
return
this
;
}
static
{
Util
.
load
();
}
}
src/share/back/SDE.c
浏览文件 @
f9ad02d9
...
...
@@ -28,6 +28,12 @@
#include "util.h"
#include "SDE.h"
#ifdef __APPLE__
/* use setjmp/longjmp versions that do not save/restore the signal mask */
#define setjmp _setjmp
#define longjmp _longjmp
#endif
/**
* This SourceDebugExtension code does not
* allow concurrent translation - due to caching method.
...
...
src/share/classes/com/sun/tools/attach/VirtualMachine.java
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2005, 20
06
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 20
13
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -59,7 +59,7 @@ import java.io.IOException;
* {@link java.lang.instrument} for a detailed description on how these agents
* are loaded and started). The {@link #loadAgentLibrary loadAgentLibrary} and
* {@link #loadAgentPath loadAgentPath} methods are used to load agents that
* are deployed
in a dynamic library
and make use of the <a
* are deployed
either in a dynamic library or statically linked into the VM
and make use of the <a
* href="../../../../../../../../technotes/guides/jvmti/index.html">JVM Tools
* Interface</a>. </p>
*
...
...
@@ -298,25 +298,29 @@ public abstract class VirtualMachine {
* <p> A <a href="../../../../../../../../technotes/guides/jvmti/index.html">JVM
* TI</a> client is called an <i>agent</i>. It is developed in a native language.
* A JVM TI agent is deployed in a platform specific manner but it is typically the
* platform equivalent of a dynamic library. This method causes the given agent
* library to be loaded into the target VM (if not already loaded).
* platform equivalent of a dynamic library. Alternatively, it may be statically linked into the VM.
* This method causes the given agent library to be loaded into the target
* VM (if not already loaded or if not statically linked into the VM).
* It then causes the target VM to invoke the <code>Agent_OnAttach</code> function
* or, for a statically linked agent named 'L', the <code>Agent_OnAttach_L</code> function
* as specified in the
* <a href="../../../../../../../../technotes/guides/jvmti/index.html"> JVM Tools
* Interface</a> specification. Note that the <code>Agent_OnAttach</code>
* Interface</a> specification. Note that the <code>Agent_OnAttach
[_L]
</code>
* function is invoked even if the agent library was loaded prior to invoking
* this method.
*
* <p> The agent library provided is the name of the agent library. It is interpreted
* in the target virtual machine in an implementation-dependent manner. Typically an
* implementation will expand the library name into an operating system specific file
* name. For example, on UNIX systems, the name <tt>foo</tt> might be expanded to
* <tt>libfoo.so</tt>, and located using the search path specified by the
* <tt>LD_LIBRARY_PATH</tt> environment variable.</p>
* name. For example, on UNIX systems, the name <tt>L</tt> might be expanded to
* <tt>libL.so</tt>, and located using the search path specified by the
* <tt>LD_LIBRARY_PATH</tt> environment variable. If the agent named 'L' is
* statically linked into the VM then the VM must export a function named
* <code>Agent_OnAttach_L</code>.</p>
*
* <p> If the <code>Agent_OnAttach</code> function in the agent library returns
* <p> If the <code>Agent_OnAttach
[_L]
</code> function in the agent library returns
* an error then an {@link com.sun.tools.attach.AgentInitializationException} is
* thrown. The return value from the <code>Agent_OnAttach</code> can then be
* thrown. The return value from the <code>Agent_OnAttach
[_L]
</code> can then be
* obtained by invoking the {@link
* com.sun.tools.attach.AgentInitializationException#returnValue() returnValue}
* method on the exception. </p>
...
...
@@ -325,15 +329,16 @@ public abstract class VirtualMachine {
* The name of the agent library.
*
* @param options
* The options to provide to the <code>Agent_OnAttach</code>
* The options to provide to the <code>Agent_OnAttach
[_L]
</code>
* function (can be <code>null</code>).
*
* @throws AgentLoadException
* If the agent library does not exist, or cannot be loaded for
* another reason.
* If the agent library does not exist, the agent library is not
* statically linked with the VM, or the agent library cannot be
* loaded for another reason.
*
* @throws AgentInitializationException
* If the <code>Agent_OnAttach
</code> function returns an error
* If the <code>Agent_OnAttach
[_L]</code> function returns an error.
*
* @throws IOException
* If an I/O error occurs
...
...
@@ -359,11 +364,12 @@ public abstract class VirtualMachine {
* The name of the agent library.
*
* @throws AgentLoadException
* If the agent library does not exist, or cannot be loaded for
* another reason.
* If the agent library does not exist, the agent library is not
* statically linked with the VM, or the agent library cannot be
* loaded for another reason.
*
* @throws AgentInitializationException
* If the <code>Agent_OnAttach
</code> function returns an error
* If the <code>Agent_OnAttach
[_L]</code> function returns an error.
*
* @throws IOException
* If an I/O error occurs
...
...
@@ -383,12 +389,23 @@ public abstract class VirtualMachine {
* <p> A <a href="../../../../../../../../technotes/guides/jvmti/index.html">JVM
* TI</a> client is called an <i>agent</i>. It is developed in a native language.
* A JVM TI agent is deployed in a platform specific manner but it is typically the
* platform equivalent of a dynamic library. This method causes the given agent
* library to be loaded into the target VM (if not already loaded).
* It then causes the target VM to invoke the <code>Agent_OnAttach</code> function
* as specified in the
* platform equivalent of a dynamic library. Alternatively, the native
* library specified by the agentPath parameter may be statically
* linked with the VM. The parsing of the agentPath parameter into
* a statically linked library name is done in a platform
* specific manner in the VM. For example, in UNIX, an agentPath parameter
* of <code>/a/b/libL.so</code> would name a library 'L'.
*
* See the JVM TI Specification for more details.
*
* This method causes the given agent library to be loaded into the target
* VM (if not already loaded or if not statically linked into the VM).
* It then causes the target VM to invoke the <code>Agent_OnAttach</code>
* function or, for a statically linked agent named 'L', the
* <code>Agent_OnAttach_L</code> function as specified in the
* <a href="../../../../../../../../technotes/guides/jvmti/index.html"> JVM Tools
* Interface</a> specification. Note that the <code>Agent_OnAttach</code>
* Interface</a> specification.
* Note that the <code>Agent_OnAttach[_L]</code>
* function is invoked even if the agent library was loaded prior to invoking
* this method.
*
...
...
@@ -396,9 +413,9 @@ public abstract class VirtualMachine {
* agent library. Unlike {@link #loadAgentLibrary loadAgentLibrary}, the library name
* is not expanded in the target virtual machine. </p>
*
* <p> If the <code>Agent_OnAttach</code> function in the agent library returns
* <p> If the <code>Agent_OnAttach
[_L]
</code> function in the agent library returns
* an error then an {@link com.sun.tools.attach.AgentInitializationException} is
* thrown. The return value from the <code>Agent_OnAttach</code> can then be
* thrown. The return value from the <code>Agent_OnAttach
[_L]
</code> can then be
* obtained by invoking the {@link
* com.sun.tools.attach.AgentInitializationException#returnValue() returnValue}
* method on the exception. </p>
...
...
@@ -407,15 +424,16 @@ public abstract class VirtualMachine {
* The full path of the agent library.
*
* @param options
* The options to provide to the <code>Agent_OnAttach</code>
* The options to provide to the <code>Agent_OnAttach
[_L]
</code>
* function (can be <code>null</code>).
*
* @throws AgentLoadException
* If the agent library does not exist, or cannot be loaded for
* another reason.
* If the agent library does not exist, the agent library is not
* statically linked with the VM, or the agent library cannot be
* loaded for another reason.
*
* @throws AgentInitializationException
* If the <code>Agent_OnAttach
</code> function returns an error
* If the <code>Agent_OnAttach
[_L]</code> function returns an error.
*
* @throws IOException
* If an I/O error occurs
...
...
@@ -441,11 +459,12 @@ public abstract class VirtualMachine {
* The full path to the agent library.
*
* @throws AgentLoadException
* If the agent library does not exist, or cannot be loaded for
* another reason.
* If the agent library does not exist, the agent library is not
* statically linked with the VM, or the agent library cannot be
* loaded for another reason.
*
* @throws AgentInitializationException
* If the <code>Agent_OnAttach
</code> function returns an error
* If the <code>Agent_OnAttach
[_L]</code> function returns an error.
*
* @throws IOException
* If an I/O error occurs
...
...
src/share/classes/java/io/BufferedInputStream.java
浏览文件 @
f9ad02d9
/*
* Copyright (c) 1994, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -50,7 +50,15 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
public
class
BufferedInputStream
extends
FilterInputStream
{
private
static
int
defaultBufferSize
=
8192
;
private
static
int
DEFAULT_BUFFER_SIZE
=
8192
;
/**
* The maximum size of array to allocate.
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private
static
int
MAX_BUFFER_SIZE
=
Integer
.
MAX_VALUE
-
8
;
/**
* The internal buffer array where the data is stored. When necessary,
...
...
@@ -172,7 +180,7 @@ class BufferedInputStream extends FilterInputStream {
* @param in the underlying input stream.
*/
public
BufferedInputStream
(
InputStream
in
)
{
this
(
in
,
defaultBufferSize
);
this
(
in
,
DEFAULT_BUFFER_SIZE
);
}
/**
...
...
@@ -215,8 +223,11 @@ class BufferedInputStream extends FilterInputStream {
}
else
if
(
buffer
.
length
>=
marklimit
)
{
markpos
=
-
1
;
/* buffer got too big, invalidate mark */
pos
=
0
;
/* drop buffer contents */
}
else
if
(
buffer
.
length
>=
MAX_BUFFER_SIZE
)
{
throw
new
OutOfMemoryError
(
"Required array size too large"
);
}
else
{
/* grow buffer */
int
nsz
=
pos
*
2
;
int
nsz
=
(
pos
<=
MAX_BUFFER_SIZE
-
pos
)
?
pos
*
2
:
MAX_BUFFER_SIZE
;
if
(
nsz
>
marklimit
)
nsz
=
marklimit
;
byte
nbuf
[]
=
new
byte
[
nsz
];
...
...
src/share/classes/java/lang/AbstractStringBuilder.java
浏览文件 @
f9ad02d9
...
...
@@ -1307,7 +1307,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* specified substring, starting at the specified index. The integer
* returned is the smallest value {@code k} for which:
* <blockquote><pre>
* k >= Math.min(fromIndex,
str
.length()) &&
* k >= Math.min(fromIndex,
this
.length()) &&
* this.toString().startsWith(str, k)
* </pre></blockquote>
* If no such value of <i>k</i> exists, then -1 is returned.
...
...
@@ -1346,7 +1346,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* specified substring. The integer returned is the largest value <i>k</i>
* such that:
* <blockquote><pre>
* k <= Math.min(fromIndex,
str
.length()) &&
* k <= Math.min(fromIndex,
this
.length()) &&
* this.toString().startsWith(str, k)
* </pre></blockquote>
* If no such value of <i>k</i> exists, then -1 is returned.
...
...
src/share/classes/java/lang/Class.java
浏览文件 @
f9ad02d9
...
...
@@ -3338,8 +3338,16 @@ public final class Class<T> implements java.io.Serializable,
* @since 1.8
*/
public
AnnotatedType
getAnnotatedSuperclass
()
{
if
(
this
==
Object
.
class
||
isInterface
()
||
isArray
()
||
isPrimitive
()
||
this
==
Void
.
TYPE
)
{
return
null
;
}
return
TypeAnnotationParser
.
buildAnnotatedSuperclass
(
getRawTypeAnnotations
(),
getConstantPool
(),
this
);
}
}
/**
* Returns an array of AnnotatedType objects that represent the use of types to
...
...
src/share/classes/java/lang/Math.java
浏览文件 @
f9ad02d9
...
...
@@ -698,11 +698,8 @@ public final class Math {
return
0
;
}
private
static
Random
randomNumberGenerator
;
private
static
synchronized
Random
initRNG
()
{
Random
rnd
=
randomNumberGenerator
;
return
(
rnd
==
null
)
?
(
randomNumberGenerator
=
new
Random
())
:
rnd
;
private
static
final
class
RandomNumberGeneratorHolder
{
static
final
Random
randomNumberGenerator
=
new
Random
();
}
/**
...
...
@@ -729,9 +726,7 @@ public final class Math {
* @see Random#nextDouble()
*/
public
static
double
random
()
{
Random
rnd
=
randomNumberGenerator
;
if
(
rnd
==
null
)
rnd
=
initRNG
();
return
rnd
.
nextDouble
();
return
RandomNumberGeneratorHolder
.
randomNumberGenerator
.
nextDouble
();
}
/**
...
...
src/share/classes/java/lang/ProcessBuilder.java
浏览文件 @
f9ad02d9
...
...
@@ -29,7 +29,6 @@ import java.io.File;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.security.AccessControlException
;
import
java.util.Arrays
;
import
java.util.ArrayList
;
import
java.util.List
;
...
...
@@ -1033,9 +1032,9 @@ public final class ProcessBuilder
// Can not disclose the fail reason for read-protected files.
try
{
security
.
checkRead
(
prog
);
}
catch
(
AccessControlException
ac
e
)
{
}
catch
(
SecurityException
s
e
)
{
exceptionInfo
=
""
;
cause
=
ac
e
;
cause
=
s
e
;
}
}
// It's much easier for us to create a high-quality error
...
...
src/share/classes/java/lang/StrictMath.java
浏览文件 @
f9ad02d9
...
...
@@ -678,11 +678,8 @@ public final class StrictMath {
return
Math
.
round
(
a
);
}
private
static
Random
randomNumberGenerator
;
private
static
synchronized
Random
initRNG
()
{
Random
rnd
=
randomNumberGenerator
;
return
(
rnd
==
null
)
?
(
randomNumberGenerator
=
new
Random
())
:
rnd
;
private
static
final
class
RandomNumberGeneratorHolder
{
static
final
Random
randomNumberGenerator
=
new
Random
();
}
/**
...
...
@@ -709,9 +706,7 @@ public final class StrictMath {
* @see Random#nextDouble()
*/
public
static
double
random
()
{
Random
rnd
=
randomNumberGenerator
;
if
(
rnd
==
null
)
rnd
=
initRNG
();
return
rnd
.
nextDouble
();
return
RandomNumberGeneratorHolder
.
randomNumberGenerator
.
nextDouble
();
}
/**
...
...
src/share/classes/java/math/BigDecimal.java
浏览文件 @
f9ad02d9
...
...
@@ -2659,28 +2659,32 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
if
(
ys
==
0
)
return
1
;
int
sdiff
=
this
.
scale
-
val
.
scale
;
long
sdiff
=
(
long
)
this
.
scale
-
val
.
scale
;
if
(
sdiff
!=
0
)
{
// Avoid matching scales if the (adjusted) exponents differ
int
xae
=
this
.
precision
()
-
this
.
scale
;
// [-1]
int
yae
=
val
.
precision
()
-
val
.
scale
;
// [-1]
long
xae
=
(
long
)
this
.
precision
()
-
this
.
scale
;
// [-1]
long
yae
=
(
long
)
val
.
precision
()
-
val
.
scale
;
// [-1]
if
(
xae
<
yae
)
return
-
1
;
if
(
xae
>
yae
)
return
1
;
BigInteger
rb
=
null
;
if
(
sdiff
<
0
)
{
if
(
(
xs
==
INFLATED
||
(
xs
=
longMultiplyPowerTen
(
xs
,
-
sdiff
))
==
INFLATED
)
&&
// The cases sdiff <= Integer.MIN_VALUE intentionally fall through.
if
(
sdiff
>
Integer
.
MIN_VALUE
&&
(
xs
==
INFLATED
||
(
xs
=
longMultiplyPowerTen
(
xs
,
(
int
)-
sdiff
))
==
INFLATED
)
&&
ys
==
INFLATED
)
{
rb
=
bigMultiplyPowerTen
(-
sdiff
);
rb
=
bigMultiplyPowerTen
(
(
int
)
-
sdiff
);
return
rb
.
compareMagnitude
(
val
.
intVal
);
}
}
else
{
// sdiff > 0
if
(
(
ys
==
INFLATED
||
(
ys
=
longMultiplyPowerTen
(
ys
,
sdiff
))
==
INFLATED
)
&&
// The cases sdiff > Integer.MAX_VALUE intentionally fall through.
if
(
sdiff
<=
Integer
.
MAX_VALUE
&&
(
ys
==
INFLATED
||
(
ys
=
longMultiplyPowerTen
(
ys
,
(
int
)
sdiff
))
==
INFLATED
)
&&
xs
==
INFLATED
)
{
rb
=
val
.
bigMultiplyPowerTen
(
sdiff
);
rb
=
val
.
bigMultiplyPowerTen
(
(
int
)
sdiff
);
return
this
.
intVal
.
compareMagnitude
(
rb
);
}
}
...
...
@@ -4545,7 +4549,7 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
if
(
cmp
>
0
)
{
// satisfy constraint (b)
yscale
-=
1
;
// [that is, divisor *= 10]
int
scl
=
checkScaleNonZero
(
preferredScale
+
yscale
-
xscale
+
mcp
);
if
(
checkScaleNonZero
((
long
)
mcp
+
yscale
)
>
xscale
)
{
if
(
checkScaleNonZero
((
long
)
mcp
+
yscale
-
xscale
)
>
0
)
{
// assert newScale >= xscale
int
raise
=
checkScaleNonZero
((
long
)
mcp
+
yscale
-
xscale
);
long
scaledXs
;
...
...
@@ -4626,7 +4630,7 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
// return BigDecimal object whose scale will be set to 'scl'.
int
scl
=
checkScaleNonZero
(
preferredScale
+
yscale
-
xscale
+
mcp
);
BigDecimal
quotient
;
if
(
checkScaleNonZero
((
long
)
mcp
+
yscale
)
>
xscale
)
{
if
(
checkScaleNonZero
((
long
)
mcp
+
yscale
-
xscale
)
>
0
)
{
int
raise
=
checkScaleNonZero
((
long
)
mcp
+
yscale
-
xscale
);
long
scaledXs
;
if
((
scaledXs
=
longMultiplyPowerTen
(
xs
,
raise
))
==
INFLATED
)
{
...
...
@@ -4673,7 +4677,7 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
// return BigDecimal object whose scale will be set to 'scl'.
BigDecimal
quotient
;
int
scl
=
checkScaleNonZero
(
preferredScale
+
yscale
-
xscale
+
mcp
);
if
(
checkScaleNonZero
((
long
)
mcp
+
yscale
)
>
xscale
)
{
if
(
checkScaleNonZero
((
long
)
mcp
+
yscale
-
xscale
)
>
0
)
{
int
raise
=
checkScaleNonZero
((
long
)
mcp
+
yscale
-
xscale
);
BigInteger
rb
=
bigMultiplyPowerTen
(
xs
,
raise
);
quotient
=
divideAndRound
(
rb
,
ys
,
scl
,
roundingMode
,
checkScaleNonZero
(
preferredScale
));
...
...
@@ -4714,7 +4718,7 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
// return BigDecimal object whose scale will be set to 'scl'.
BigDecimal
quotient
;
int
scl
=
checkScaleNonZero
(
preferredScale
+
yscale
-
xscale
+
mcp
);
if
(
checkScaleNonZero
((
long
)
mcp
+
yscale
)
>
xscale
)
{
if
(
checkScaleNonZero
((
long
)
mcp
+
yscale
-
xscale
)
>
0
)
{
int
raise
=
checkScaleNonZero
((
long
)
mcp
+
yscale
-
xscale
);
BigInteger
rb
=
bigMultiplyPowerTen
(
xs
,
raise
);
quotient
=
divideAndRound
(
rb
,
ys
,
scl
,
roundingMode
,
checkScaleNonZero
(
preferredScale
));
...
...
@@ -4745,7 +4749,7 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
// return BigDecimal object whose scale will be set to 'scl'.
BigDecimal
quotient
;
int
scl
=
checkScaleNonZero
(
preferredScale
+
yscale
-
xscale
+
mcp
);
if
(
checkScaleNonZero
((
long
)
mcp
+
yscale
)
>
xscale
)
{
if
(
checkScaleNonZero
((
long
)
mcp
+
yscale
-
xscale
)
>
0
)
{
int
raise
=
checkScaleNonZero
((
long
)
mcp
+
yscale
-
xscale
);
BigInteger
rb
=
bigMultiplyPowerTen
(
xs
,
raise
);
quotient
=
divideAndRound
(
rb
,
ys
,
scl
,
roundingMode
,
checkScaleNonZero
(
preferredScale
));
...
...
src/share/classes/java/math/BigInteger.java
浏览文件 @
f9ad02d9
...
...
@@ -2109,7 +2109,7 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
// This is a quick way to approximate the size of the result,
// similar to doing log2[n] * exponent. This will give an upper bound
// of how big the result can be, and which algorithm to use.
int
scaleFactor
=
remainingBits
*
exponent
;
long
scaleFactor
=
(
long
)
remainingBits
*
exponent
;
// Use slightly different algorithms for small and large operands.
// See if the result will safely fit into a long. (Largest 2^63-1)
...
...
src/share/classes/java/rmi/server/RMISocketFactory.java
浏览文件 @
f9ad02d9
...
...
@@ -50,13 +50,13 @@ import java.net.*;
* @implNote
* <p>You can use the {@code RMISocketFactory} class to create a server socket that
* is bound to a specific address, restricting the origin of requests. For example,
* the following code implements a socket factory that binds server sockets to
the
* the following code implements a socket factory that binds server sockets to
an IPv4
* loopback address. This restricts RMI to processing requests only from the local host.
*
* <pre>{@code
* class LoopbackSocketFactory extends RMISocketFactory {
* public ServerSocket createServerSocket(int port) throws IOException {
* return new ServerSocket(port, 5, InetAddress.get
LoopbackAddress(
));
* return new ServerSocket(port, 5, InetAddress.get
ByName("127.0.0.1"
));
* }
*
* public Socket createSocket(String host, int port) throws IOException {
...
...
@@ -72,8 +72,8 @@ import java.net.*;
* }</pre>
*
* Set the {@code java.rmi.server.hostname} system property
* to
a host name (typically {@code localhost}) that resolves to the loopback
*
interface to ensure that the generated stubs use the right
network interface.
* to
{@code 127.0.0.1} to ensure that the generated stubs connect to the right
* network interface.
*
* @author Ann Wollrath
* @author Peter Jones
...
...
src/share/classes/java/util/Collections.java
浏览文件 @
f9ad02d9
...
...
@@ -27,7 +27,6 @@ package java.util;
import
java.io.Serializable
;
import
java.io.ObjectOutputStream
;
import
java.io.IOException
;
import
java.io.InvalidObjectException
;
import
java.lang.reflect.Array
;
import
java.util.function.BiConsumer
;
import
java.util.function.BiFunction
;
...
...
@@ -35,6 +34,7 @@ import java.util.function.Consumer;
import
java.util.function.Function
;
import
java.util.function.Predicate
;
import
java.util.function.UnaryOperator
;
import
java.util.stream.IntStream
;
import
java.util.stream.Stream
;
import
java.util.stream.StreamSupport
;
...
...
@@ -1148,7 +1148,16 @@ public class Collections {
public
Spliterator
<
E
>
spliterator
()
{
return
(
Spliterator
<
E
>)
c
.
spliterator
();
}
@SuppressWarnings
(
"unchecked"
)
@Override
public
Stream
<
E
>
stream
()
{
return
(
Stream
<
E
>)
c
.
stream
();
}
@SuppressWarnings
(
"unchecked"
)
@Override
public
Stream
<
E
>
parallelStream
()
{
return
(
Stream
<
E
>)
c
.
parallelStream
();
}
}
/**
...
...
@@ -2009,8 +2018,8 @@ public class Collections {
* through the returned collection.<p>
*
* It is imperative that the user manually synchronize on the returned
* collection when traversing it via {@link Iterator}
or
*
{@link Spliterator
}:
* collection when traversing it via {@link Iterator}
, {@link Spliterator}
*
or {@link Stream
}:
* <pre>
* Collection c = Collections.synchronizedCollection(myCollection);
* ...
...
...
@@ -2120,6 +2129,14 @@ public class Collections {
public
Spliterator
<
E
>
spliterator
()
{
return
c
.
spliterator
();
// Must be manually synched by user!
}
@Override
public
Stream
<
E
>
stream
()
{
return
c
.
stream
();
// Must be manually synched by user!
}
@Override
public
Stream
<
E
>
parallelStream
()
{
return
c
.
parallelStream
();
// Must be manually synched by user!
}
private
void
writeObject
(
ObjectOutputStream
s
)
throws
IOException
{
synchronized
(
mutex
)
{
s
.
defaultWriteObject
();}
}
...
...
@@ -3172,6 +3189,10 @@ public class Collections {
}
@Override
public
Spliterator
<
E
>
spliterator
()
{
return
c
.
spliterator
();}
@Override
public
Stream
<
E
>
stream
()
{
return
c
.
stream
();}
@Override
public
Stream
<
E
>
parallelStream
()
{
return
c
.
parallelStream
();}
}
/**
...
...
@@ -5096,6 +5117,22 @@ public class Collections {
") > toIndex("
+
toIndex
+
")"
);
return
new
CopiesList
<>(
toIndex
-
fromIndex
,
element
);
}
// Override default methods in Collection
@Override
public
Stream
<
E
>
stream
()
{
return
IntStream
.
range
(
0
,
n
).
mapToObj
(
i
->
element
);
}
@Override
public
Stream
<
E
>
parallelStream
()
{
return
IntStream
.
range
(
0
,
n
).
parallel
().
mapToObj
(
i
->
element
);
}
@Override
public
Spliterator
<
E
>
spliterator
()
{
return
stream
().
spliterator
();
}
}
/**
...
...
@@ -5503,6 +5540,10 @@ public class Collections {
@Override
public
Spliterator
<
E
>
spliterator
()
{
return
s
.
spliterator
();}
@Override
public
Stream
<
E
>
stream
()
{
return
s
.
stream
();}
@Override
public
Stream
<
E
>
parallelStream
()
{
return
s
.
parallelStream
();}
private
static
final
long
serialVersionUID
=
2454657854757543876L
;
...
...
@@ -5568,10 +5609,14 @@ public class Collections {
@Override
public
void
forEach
(
Consumer
<?
super
E
>
action
)
{
q
.
forEach
(
action
);}
@Override
public
Spliterator
<
E
>
spliterator
()
{
return
q
.
spliterator
();}
@Override
public
boolean
removeIf
(
Predicate
<?
super
E
>
filter
)
{
return
q
.
removeIf
(
filter
);
}
@Override
public
Spliterator
<
E
>
spliterator
()
{
return
q
.
spliterator
();}
@Override
public
Stream
<
E
>
stream
()
{
return
q
.
stream
();}
@Override
public
Stream
<
E
>
parallelStream
()
{
return
q
.
parallelStream
();}
}
}
src/share/classes/java/util/ComparableTimSort.java
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright 2009 Google Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
...
...
@@ -146,7 +147,7 @@ class ComparableTimSort {
*/
int
stackLen
=
(
len
<
120
?
5
:
len
<
1542
?
10
:
len
<
119151
?
19
:
40
);
len
<
119151
?
24
:
40
);
runBase
=
new
int
[
stackLen
];
runLen
=
new
int
[
stackLen
];
}
...
...
src/share/classes/java/util/Comparator.java
浏览文件 @
f9ad02d9
...
...
@@ -199,7 +199,7 @@ public interface Comparator<T> {
* composed using following code,
*
* <pre>{@code
* Comparator<String> cmp = Comparator.comparing(String::length)
* Comparator<String> cmp = Comparator.comparing
Int
(String::length)
* .thenComparing(String.CASE_INSENSITIVE_ORDER);
* }</pre>
*
...
...
@@ -270,18 +270,18 @@ public interface Comparator<T> {
* extracts a {@code int} sort key.
*
* @implSpec This default implementation behaves as if {@code
* thenComparing(comparing(keyExtractor))}.
* thenComparing(comparing
Int
(keyExtractor))}.
*
* @param keyExtractor the function used to extract the integer sort key
* @return a lexicographic-order comparator composed of this and then the
* {@code int} sort key
* @throws NullPointerException if the argument is null.
* @see #comparing(ToIntFunction)
* @see #comparing
Int
(ToIntFunction)
* @see #thenComparing(Comparator)
* @since 1.8
*/
default
Comparator
<
T
>
thenComparing
(
ToIntFunction
<?
super
T
>
keyExtractor
)
{
return
thenComparing
(
comparing
(
keyExtractor
));
default
Comparator
<
T
>
thenComparing
Int
(
ToIntFunction
<?
super
T
>
keyExtractor
)
{
return
thenComparing
(
comparing
Int
(
keyExtractor
));
}
/**
...
...
@@ -289,18 +289,18 @@ public interface Comparator<T> {
* extracts a {@code long} sort key.
*
* @implSpec This default implementation behaves as if {@code
* thenComparing(comparing(keyExtractor))}.
* thenComparing(comparing
Long
(keyExtractor))}.
*
* @param keyExtractor the function used to extract the long sort key
* @return a lexicographic-order comparator composed of this and then the
* {@code long} sort key
* @throws NullPointerException if the argument is null.
* @see #comparing(ToLongFunction)
* @see #comparing
Long
(ToLongFunction)
* @see #thenComparing(Comparator)
* @since 1.8
*/
default
Comparator
<
T
>
thenComparing
(
ToLongFunction
<?
super
T
>
keyExtractor
)
{
return
thenComparing
(
comparing
(
keyExtractor
));
default
Comparator
<
T
>
thenComparing
Long
(
ToLongFunction
<?
super
T
>
keyExtractor
)
{
return
thenComparing
(
comparing
Long
(
keyExtractor
));
}
/**
...
...
@@ -308,18 +308,18 @@ public interface Comparator<T> {
* extracts a {@code double} sort key.
*
* @implSpec This default implementation behaves as if {@code
* thenComparing(comparing(keyExtractor))}.
* thenComparing(comparing
Double
(keyExtractor))}.
*
* @param keyExtractor the function used to extract the double sort key
* @return a lexicographic-order comparator composed of this and then the
* {@code double} sort key
* @throws NullPointerException if the argument is null.
* @see #comparing(ToDoubleFunction)
* @see #comparing
Double
(ToDoubleFunction)
* @see #thenComparing(Comparator)
* @since 1.8
*/
default
Comparator
<
T
>
thenComparing
(
ToDoubleFunction
<?
super
T
>
keyExtractor
)
{
return
thenComparing
(
comparing
(
keyExtractor
));
default
Comparator
<
T
>
thenComparing
Double
(
ToDoubleFunction
<?
super
T
>
keyExtractor
)
{
return
thenComparing
(
comparing
Double
(
keyExtractor
));
}
/**
...
...
@@ -484,7 +484,7 @@ public interface Comparator<T> {
* @throws NullPointerException if the argument is null
* @since 1.8
*/
public
static
<
T
>
Comparator
<
T
>
comparing
(
ToIntFunction
<?
super
T
>
keyExtractor
)
{
public
static
<
T
>
Comparator
<
T
>
comparing
Int
(
ToIntFunction
<?
super
T
>
keyExtractor
)
{
Objects
.
requireNonNull
(
keyExtractor
);
return
(
Comparator
<
T
>
&
Serializable
)
(
c1
,
c2
)
->
Integer
.
compare
(
keyExtractor
.
applyAsInt
(
c1
),
keyExtractor
.
applyAsInt
(
c2
));
...
...
@@ -505,7 +505,7 @@ public interface Comparator<T> {
* @throws NullPointerException if the argument is null
* @since 1.8
*/
public
static
<
T
>
Comparator
<
T
>
comparing
(
ToLongFunction
<?
super
T
>
keyExtractor
)
{
public
static
<
T
>
Comparator
<
T
>
comparing
Long
(
ToLongFunction
<?
super
T
>
keyExtractor
)
{
Objects
.
requireNonNull
(
keyExtractor
);
return
(
Comparator
<
T
>
&
Serializable
)
(
c1
,
c2
)
->
Long
.
compare
(
keyExtractor
.
applyAsLong
(
c1
),
keyExtractor
.
applyAsLong
(
c2
));
...
...
@@ -526,7 +526,7 @@ public interface Comparator<T> {
* @throws NullPointerException if the argument is null
* @since 1.8
*/
public
static
<
T
>
Comparator
<
T
>
comparing
(
ToDoubleFunction
<?
super
T
>
keyExtractor
)
{
public
static
<
T
>
Comparator
<
T
>
comparing
Double
(
ToDoubleFunction
<?
super
T
>
keyExtractor
)
{
Objects
.
requireNonNull
(
keyExtractor
);
return
(
Comparator
<
T
>
&
Serializable
)
(
c1
,
c2
)
->
Double
.
compare
(
keyExtractor
.
applyAsDouble
(
c1
),
keyExtractor
.
applyAsDouble
(
c2
));
...
...
src/share/classes/java/util/Random.java
浏览文件 @
f9ad02d9
...
...
@@ -26,9 +26,13 @@
package
java.util
;
import
java.io.*
;
import
java.util.concurrent.atomic.AtomicLong
;
import
java.util.function.DoubleConsumer
;
import
java.util.function.IntConsumer
;
import
java.util.function.LongConsumer
;
import
java.util.stream.DoubleStream
;
import
java.util.stream.IntStream
;
import
java.util.stream.LongStream
;
import
java.util.stream.StreamSupport
;
import
sun.misc.Unsafe
;
...
...
@@ -85,6 +89,13 @@ class Random implements java.io.Serializable {
private
static
final
long
addend
=
0xB
L
;
private
static
final
long
mask
=
(
1L
<<
48
)
-
1
;
private
static
final
double
DOUBLE_UNIT
=
1.0
/
(
1L
<<
53
);
// IllegalArgumentException messages
static
final
String
BadBound
=
"bound must be positive"
;
static
final
String
BadRange
=
"bound must be greater than origin"
;
static
final
String
BadSize
=
"size must be non-negative"
;
/**
* Creates a new random number generator. This constructor sets
* the seed of the random number generator to a value very likely
...
...
@@ -221,6 +232,82 @@ class Random implements java.io.Serializable {
bytes
[
i
++]
=
(
byte
)
rnd
;
}
/**
* The form of nextLong used by LongStream Spliterators. If
* origin is greater than bound, acts as unbounded form of
* nextLong, else as bounded form.
*
* @param origin the least value, unless greater than bound
* @param bound the upper bound (exclusive), must not equal origin
* @return a pseudorandom value
*/
final
long
internalNextLong
(
long
origin
,
long
bound
)
{
long
r
=
nextLong
();
if
(
origin
<
bound
)
{
long
n
=
bound
-
origin
,
m
=
n
-
1
;
if
((
n
&
m
)
==
0L
)
// power of two
r
=
(
r
&
m
)
+
origin
;
else
if
(
n
>
0L
)
{
// reject over-represented candidates
for
(
long
u
=
r
>>>
1
;
// ensure nonnegative
u
+
m
-
(
r
=
u
%
n
)
<
0L
;
// rejection check
u
=
nextLong
()
>>>
1
)
// retry
;
r
+=
origin
;
}
else
{
// range not representable as long
while
(
r
<
origin
||
r
>=
bound
)
r
=
nextLong
();
}
}
return
r
;
}
/**
* The form of nextInt used by IntStream Spliterators.
* For the unbounded case: uses nextInt().
* For the bounded case with representable range: uses nextInt(int bound)
* For the bounded case with unrepresentable range: uses nextInt()
*
* @param origin the least value, unless greater than bound
* @param bound the upper bound (exclusive), must not equal origin
* @return a pseudorandom value
*/
final
int
internalNextInt
(
int
origin
,
int
bound
)
{
if
(
origin
<
bound
)
{
int
n
=
bound
-
origin
;
if
(
n
>
0
)
{
return
nextInt
(
n
)
+
origin
;
}
else
{
// range not representable as int
int
r
;
do
{
r
=
nextInt
();
}
while
(
r
<
origin
||
r
>=
bound
);
return
r
;
}
}
else
{
return
nextInt
();
}
}
/**
* The form of nextDouble used by DoubleStream Spliterators.
*
* @param origin the least value, unless greater than bound
* @param bound the upper bound (exclusive), must not equal origin
* @return a pseudorandom value
*/
final
double
internalNextDouble
(
double
origin
,
double
bound
)
{
double
r
=
nextDouble
();
if
(
origin
<
bound
)
{
r
=
r
*
(
bound
-
origin
)
+
origin
;
if
(
r
>=
bound
)
// correct for rounding
r
=
Double
.
longBitsToDouble
(
Double
.
doubleToLongBits
(
bound
)
-
1
);
}
return
r
;
}
/**
* Returns the next pseudorandom, uniformly distributed {@code int}
* value from this random number generator's sequence. The general
...
...
@@ -247,23 +334,23 @@ class Random implements java.io.Serializable {
* between 0 (inclusive) and the specified value (exclusive), drawn from
* this random number generator's sequence. The general contract of
* {@code nextInt} is that one {@code int} value in the specified range
* is pseudorandomly generated and returned. All {@code
n
} possible
* is pseudorandomly generated and returned. All {@code
bound
} possible
* {@code int} values are produced with (approximately) equal
* probability. The method {@code nextInt(int
n
)} is implemented by
* probability. The method {@code nextInt(int
bound
)} is implemented by
* class {@code Random} as if by:
* <pre> {@code
* public int nextInt(int
n
) {
* if (
n
<= 0)
* throw new IllegalArgumentException("
n
must be positive");
* public int nextInt(int
bound
) {
* if (
bound
<= 0)
* throw new IllegalArgumentException("
bound
must be positive");
*
* if ((
n & -n) == n) // i.e., n
is a power of 2
* return (int)((
n
* (long)next(31)) >> 31);
* if ((
bound & -bound) == bound) // i.e., bound
is a power of 2
* return (int)((
bound
* (long)next(31)) >> 31);
*
* int bits, val;
* do {
* bits = next(31);
* val = bits %
n
;
* } while (bits - val + (
n
-1) < 0);
* val = bits %
bound
;
* } while (bits - val + (
bound
-1) < 0);
* return val;
* }}</pre>
*
...
...
@@ -289,28 +376,28 @@ class Random implements java.io.Serializable {
* greatly increases the length of the sequence of values returned by
* successive calls to this method if n is a small power of two.
*
* @param n the bound on the random number to be returned. Must be
* positive.
* @param bound the upper bound (exclusive). Must be positive.
* @return the next pseudorandom, uniformly distributed {@code int}
* value between
{@code 0} (inclusive) and {@code n
} (exclusive)
* value between
zero (inclusive) and {@code bound
} (exclusive)
* from this random number generator's sequence
* @throws IllegalArgumentException if
n
is not positive
* @throws IllegalArgumentException if
bound
is not positive
* @since 1.2
*/
public
int
nextInt
(
int
bound
)
{
if
(
bound
<=
0
)
throw
new
IllegalArgumentException
(
BadBound
);
public
int
nextInt
(
int
n
)
{
if
(
n
<=
0
)
throw
new
IllegalArgumentException
(
"n must be positive"
);
if
((
n
&
-
n
)
==
n
)
// i.e., n is a power of 2
return
(
int
)((
n
*
(
long
)
next
(
31
))
>>
31
);
int
bits
,
val
;
do
{
bits
=
next
(
31
);
val
=
bits
%
n
;
}
while
(
bits
-
val
+
(
n
-
1
)
<
0
);
return
val
;
int
r
=
next
(
31
);
int
m
=
bound
-
1
;
if
((
bound
&
m
)
==
0
)
// i.e., bound is a power of 2
r
=
(
int
)((
bound
*
(
long
)
r
)
>>
31
);
else
{
for
(
int
u
=
r
;
u
-
(
r
=
u
%
bound
)
+
m
<
0
;
u
=
next
(
31
))
;
}
return
r
;
}
/**
...
...
@@ -442,8 +529,7 @@ class Random implements java.io.Serializable {
* @see Math#random
*/
public
double
nextDouble
()
{
return
(((
long
)(
next
(
26
))
<<
27
)
+
next
(
27
))
/
(
double
)(
1L
<<
53
);
return
(((
long
)(
next
(
26
))
<<
27
)
+
next
(
27
))
*
DOUBLE_UNIT
;
}
private
double
nextNextGaussian
;
...
...
@@ -513,57 +599,563 @@ class Random implements java.io.Serializable {
}
}
// stream methods, coded in a way intended to better isolate for
// maintenance purposes the small differences across forms.
/**
* Returns a stream producing the given {@code streamSize} number of
* pseudorandom {@code int} values.
*
* <p>A pseudorandom {@code int} value is generated as if it's the result of
* calling the method {@link #nextInt()}.
*
* @param streamSize the number of values to generate
* @return a stream of pseudorandom {@code int} values
* @throws IllegalArgumentException if {@code streamSize} is
* less than zero
* @since 1.8
*/
public
IntStream
ints
(
long
streamSize
)
{
if
(
streamSize
<
0L
)
throw
new
IllegalArgumentException
(
BadSize
);
return
StreamSupport
.
intStream
(
new
RandomIntsSpliterator
(
this
,
0L
,
streamSize
,
Integer
.
MAX_VALUE
,
0
),
false
);
}
/**
* Returns a stream of pseudorandom, uniformly distributed
* {@code integer} values from this random number generator's
* sequence. Values are obtained as needed by calling
* {@link #nextInt()}.
* Returns an effectively unlimited stream of pseudorandom {@code int}
* values.
*
* <p>A pseudorandom {@code int} value is generated as if it's the result of
* calling the method {@link #nextInt()}.
*
* @implNote This method is implemented to be equivalent to {@code
* ints(Long.MAX_VALUE)}.
*
* @return a
n infinite stream of {@code integer
} values
* @return a
stream of pseudorandom {@code int
} values
* @since 1.8
*/
public
IntStream
ints
()
{
return
IntStream
.
generate
(
this
::
nextInt
);
return
StreamSupport
.
intStream
(
new
RandomIntsSpliterator
(
this
,
0L
,
Long
.
MAX_VALUE
,
Integer
.
MAX_VALUE
,
0
),
false
);
}
/**
* Returns a stream producing the given {@code streamSize} number
* of pseudorandom {@code int} values, each conforming to the given
* origin (inclusive) and bound (exclusive).
*
* <p>A pseudorandom {@code int} value is generated as if it's the result of
* calling the following method with the origin and bound:
* <pre> {@code
* int nextInt(int origin, int bound) {
* int n = bound - origin;
* if (n > 0) {
* return nextInt(n) + origin;
* }
* else { // range not representable as int
* int r;
* do {
* r = nextInt();
* } while (r < origin || r >= bound);
* return r;
* }
* }}</pre>
*
* @param streamSize the number of values to generate
* @param randomNumberOrigin the origin (inclusive) of each random value
* @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code int} values,
* each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException if {@code streamSize} is
* less than zero, or {@code randomNumberOrigin}
* is greater than or equal to {@code randomNumberBound}
* @since 1.8
*/
public
IntStream
ints
(
long
streamSize
,
int
randomNumberOrigin
,
int
randomNumberBound
)
{
if
(
streamSize
<
0L
)
throw
new
IllegalArgumentException
(
BadSize
);
if
(
randomNumberOrigin
>=
randomNumberBound
)
throw
new
IllegalArgumentException
(
BadRange
);
return
StreamSupport
.
intStream
(
new
RandomIntsSpliterator
(
this
,
0L
,
streamSize
,
randomNumberOrigin
,
randomNumberBound
),
false
);
}
/**
* Returns an effectively unlimited stream of pseudorandom {@code
* int} values, each conforming to the given origin (inclusive) and bound
* (exclusive).
*
* <p>A pseudorandom {@code int} value is generated as if it's the result of
* calling the following method with the origin and bound:
* <pre> {@code
* int nextInt(int origin, int bound) {
* int n = bound - origin;
* if (n > 0) {
* return nextInt(n) + origin;
* }
* else { // range not representable as int
* int r;
* do {
* r = nextInt();
* } while (r < origin || r >= bound);
* return r;
* }
* }}</pre>
*
* @implNote This method is implemented to be equivalent to {@code
* ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
*
* @param randomNumberOrigin the origin (inclusive) of each random value
* @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code int} values,
* each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException if {@code randomNumberOrigin}
* is greater than or equal to {@code randomNumberBound}
* @since 1.8
*/
public
IntStream
ints
(
int
randomNumberOrigin
,
int
randomNumberBound
)
{
if
(
randomNumberOrigin
>=
randomNumberBound
)
throw
new
IllegalArgumentException
(
BadRange
);
return
StreamSupport
.
intStream
(
new
RandomIntsSpliterator
(
this
,
0L
,
Long
.
MAX_VALUE
,
randomNumberOrigin
,
randomNumberBound
),
false
);
}
/**
* Returns a stream of pseudorandom, uniformly distributed
* {@code long} values from this random number generator's
* sequence. Values are obtained as needed by calling
* {@link #nextLong()}.
* Returns a stream producing the given {@code streamSize} number of
* pseudorandom {@code long} values.
*
* <p>A pseudorandom {@code long} value is generated as if it's the result
* of calling the method {@link #nextLong()}.
*
* @return an infinite stream of {@code long} values
* @param streamSize the number of values to generate
* @return a stream of pseudorandom {@code long} values
* @throws IllegalArgumentException if {@code streamSize} is
* less than zero
* @since 1.8
*/
public
LongStream
longs
(
long
streamSize
)
{
if
(
streamSize
<
0L
)
throw
new
IllegalArgumentException
(
BadSize
);
return
StreamSupport
.
longStream
(
new
RandomLongsSpliterator
(
this
,
0L
,
streamSize
,
Long
.
MAX_VALUE
,
0L
),
false
);
}
/**
* Returns an effectively unlimited stream of pseudorandom {@code long}
* values.
*
* <p>A pseudorandom {@code long} value is generated as if it's the result
* of calling the method {@link #nextLong()}.
*
* @implNote This method is implemented to be equivalent to {@code
* longs(Long.MAX_VALUE)}.
*
* @return a stream of pseudorandom {@code long} values
* @since 1.8
*/
public
LongStream
longs
()
{
return
LongStream
.
generate
(
this
::
nextLong
);
return
StreamSupport
.
longStream
(
new
RandomLongsSpliterator
(
this
,
0L
,
Long
.
MAX_VALUE
,
Long
.
MAX_VALUE
,
0L
),
false
);
}
/**
* Returns a stream producing the given {@code streamSize} number of
* pseudorandom {@code long}, each conforming to the given origin
* (inclusive) and bound (exclusive).
*
* <p>A pseudorandom {@code long} value is generated as if it's the result
* of calling the following method with the origin and bound:
* <pre> {@code
* long nextLong(long origin, long bound) {
* long r = nextLong();
* long n = bound - origin, m = n - 1;
* if ((n & m) == 0L) // power of two
* r = (r & m) + origin;
* else if (n > 0L) { // reject over-represented candidates
* for (long u = r >>> 1; // ensure nonnegative
* u + m - (r = u % n) < 0L; // rejection check
* u = nextLong() >>> 1) // retry
* ;
* r += origin;
* }
* else { // range not representable as long
* while (r < origin || r >= bound)
* r = nextLong();
* }
* return r;
* }}</pre>
*
* @param streamSize the number of values to generate
* @param randomNumberOrigin the origin (inclusive) of each random value
* @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code long} values,
* each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException if {@code streamSize} is
* less than zero, or {@code randomNumberOrigin}
* is greater than or equal to {@code randomNumberBound}
* @since 1.8
*/
public
LongStream
longs
(
long
streamSize
,
long
randomNumberOrigin
,
long
randomNumberBound
)
{
if
(
streamSize
<
0L
)
throw
new
IllegalArgumentException
(
BadSize
);
if
(
randomNumberOrigin
>=
randomNumberBound
)
throw
new
IllegalArgumentException
(
BadRange
);
return
StreamSupport
.
longStream
(
new
RandomLongsSpliterator
(
this
,
0L
,
streamSize
,
randomNumberOrigin
,
randomNumberBound
),
false
);
}
/**
* Returns an effectively unlimited stream of pseudorandom {@code
* long} values, each conforming to the given origin (inclusive) and bound
* (exclusive).
*
* <p>A pseudorandom {@code long} value is generated as if it's the result
* of calling the following method with the origin and bound:
* <pre> {@code
* long nextLong(long origin, long bound) {
* long r = nextLong();
* long n = bound - origin, m = n - 1;
* if ((n & m) == 0L) // power of two
* r = (r & m) + origin;
* else if (n > 0L) { // reject over-represented candidates
* for (long u = r >>> 1; // ensure nonnegative
* u + m - (r = u % n) < 0L; // rejection check
* u = nextLong() >>> 1) // retry
* ;
* r += origin;
* }
* else { // range not representable as long
* while (r < origin || r >= bound)
* r = nextLong();
* }
* return r;
* }}</pre>
*
* @implNote This method is implemented to be equivalent to {@code
* longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
*
* @param randomNumberOrigin the origin (inclusive) of each random value
* @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code long} values,
* each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException if {@code randomNumberOrigin}
* is greater than or equal to {@code randomNumberBound}
* @since 1.8
*/
public
LongStream
longs
(
long
randomNumberOrigin
,
long
randomNumberBound
)
{
if
(
randomNumberOrigin
>=
randomNumberBound
)
throw
new
IllegalArgumentException
(
BadRange
);
return
StreamSupport
.
longStream
(
new
RandomLongsSpliterator
(
this
,
0L
,
Long
.
MAX_VALUE
,
randomNumberOrigin
,
randomNumberBound
),
false
);
}
/**
* Returns a stream of pseudorandom, uniformly distributed
* {@code double} values between {@code 0.0} and {@code 1.0}
* from this random number generator's sequence. Values are
* obtained as needed by calling {@link #nextDouble()}.
* Returns a stream producing the given {@code streamSize} number of
* pseudorandom {@code double} values, each between zero
* (inclusive) and one (exclusive).
*
* @return an infinite stream of {@code double} values
* <p>A pseudorandom {@code double} value is generated as if it's the result
* of calling the method {@link #nextDouble()}}.
*
* @param streamSize the number of values to generate
* @return a stream of {@code double} values
* @throws IllegalArgumentException if {@code streamSize} is
* less than zero
* @since 1.8
*/
public
DoubleStream
doubles
(
long
streamSize
)
{
if
(
streamSize
<
0L
)
throw
new
IllegalArgumentException
(
BadSize
);
return
StreamSupport
.
doubleStream
(
new
RandomDoublesSpliterator
(
this
,
0L
,
streamSize
,
Double
.
MAX_VALUE
,
0.0
),
false
);
}
/**
* Returns an effectively unlimited stream of pseudorandom {@code
* double} values, each between zero (inclusive) and one
* (exclusive).
*
* <p>A pseudorandom {@code double} value is generated as if it's the result
* of calling the method {@link #nextDouble()}}.
*
* @implNote This method is implemented to be equivalent to {@code
* doubles(Long.MAX_VALUE)}.
*
* @return a stream of pseudorandom {@code double} values
* @since 1.8
*/
public
DoubleStream
doubles
()
{
return
DoubleStream
.
generate
(
this
::
nextDouble
);
return
StreamSupport
.
doubleStream
(
new
RandomDoublesSpliterator
(
this
,
0L
,
Long
.
MAX_VALUE
,
Double
.
MAX_VALUE
,
0.0
),
false
);
}
/**
* Returns a stream producing the given {@code streamSize} number of
* pseudorandom {@code double} values, each conforming to the given origin
* (inclusive) and bound (exclusive).
*
* <p>A pseudorandom {@code double} value is generated as if it's the result
* of calling the following method with the origin and bound:
* <pre> {@code
* double nextDouble(double origin, double bound) {
* double r = nextDouble();
* r = r * (bound - origin) + origin;
* if (r >= bound) // correct for rounding
* r = Math.nextDown(bound);
* return r;
* }}</pre>
*
* @param streamSize the number of values to generate
* @param randomNumberOrigin the origin (inclusive) of each random value
* @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code double} values,
* each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException if {@code streamSize} is
* less than zero
* @throws IllegalArgumentException if {@code randomNumberOrigin}
* is greater than or equal to {@code randomNumberBound}
* @since 1.8
*/
public
DoubleStream
doubles
(
long
streamSize
,
double
randomNumberOrigin
,
double
randomNumberBound
)
{
if
(
streamSize
<
0L
)
throw
new
IllegalArgumentException
(
BadSize
);
if
(!(
randomNumberOrigin
<
randomNumberBound
))
throw
new
IllegalArgumentException
(
BadRange
);
return
StreamSupport
.
doubleStream
(
new
RandomDoublesSpliterator
(
this
,
0L
,
streamSize
,
randomNumberOrigin
,
randomNumberBound
),
false
);
}
/**
* Returns a stream of pseudorandom, Gaussian ("normally")
* distributed {@code double} values with mean {@code 0.0}
* and standard deviation {@code 1.0} from this random number
* generator's sequence. Values are obtained as needed by
* calling {@link #nextGaussian()}.
* Returns an effectively unlimited stream of pseudorandom {@code
* double} values, each conforming to the given origin (inclusive) and bound
* (exclusive).
*
* <p>A pseudorandom {@code double} value is generated as if it's the result
* of calling the following method with the origin and bound:
* <pre> {@code
* double nextDouble(double origin, double bound) {
* double r = nextDouble();
* r = r * (bound - origin) + origin;
* if (r >= bound) // correct for rounding
* r = Math.nextDown(bound);
* return r;
* }}</pre>
*
* @implNote This method is implemented to be equivalent to {@code
* doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
*
* @return an infinite stream of {@code double} values
* @param randomNumberOrigin the origin (inclusive) of each random value
* @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code double} values,
* each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException if {@code randomNumberOrigin}
* is greater than or equal to {@code randomNumberBound}
* @since 1.8
*/
public
DoubleStream
gaussians
()
{
return
DoubleStream
.
generate
(
this
::
nextGaussian
);
public
DoubleStream
doubles
(
double
randomNumberOrigin
,
double
randomNumberBound
)
{
if
(!(
randomNumberOrigin
<
randomNumberBound
))
throw
new
IllegalArgumentException
(
BadRange
);
return
StreamSupport
.
doubleStream
(
new
RandomDoublesSpliterator
(
this
,
0L
,
Long
.
MAX_VALUE
,
randomNumberOrigin
,
randomNumberBound
),
false
);
}
/**
* Spliterator for int streams. We multiplex the four int
* versions into one class by treating a bound less than origin as
* unbounded, and also by treating "infinite" as equivalent to
* Long.MAX_VALUE. For splits, it uses the standard divide-by-two
* approach. The long and double versions of this class are
* identical except for types.
*/
static
final
class
RandomIntsSpliterator
implements
Spliterator
.
OfInt
{
final
Random
rng
;
long
index
;
final
long
fence
;
final
int
origin
;
final
int
bound
;
RandomIntsSpliterator
(
Random
rng
,
long
index
,
long
fence
,
int
origin
,
int
bound
)
{
this
.
rng
=
rng
;
this
.
index
=
index
;
this
.
fence
=
fence
;
this
.
origin
=
origin
;
this
.
bound
=
bound
;
}
public
RandomIntsSpliterator
trySplit
()
{
long
i
=
index
,
m
=
(
i
+
fence
)
>>>
1
;
return
(
m
<=
i
)
?
null
:
new
RandomIntsSpliterator
(
rng
,
i
,
index
=
m
,
origin
,
bound
);
}
public
long
estimateSize
()
{
return
fence
-
index
;
}
public
int
characteristics
()
{
return
(
Spliterator
.
SIZED
|
Spliterator
.
SUBSIZED
|
Spliterator
.
NONNULL
|
Spliterator
.
IMMUTABLE
);
}
public
boolean
tryAdvance
(
IntConsumer
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
consumer
.
accept
(
rng
.
internalNextInt
(
origin
,
bound
));
index
=
i
+
1
;
return
true
;
}
return
false
;
}
public
void
forEachRemaining
(
IntConsumer
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
index
=
f
;
Random
r
=
rng
;
int
o
=
origin
,
b
=
bound
;
do
{
consumer
.
accept
(
r
.
internalNextInt
(
o
,
b
));
}
while
(++
i
<
f
);
}
}
}
/**
* Spliterator for long streams.
*/
static
final
class
RandomLongsSpliterator
implements
Spliterator
.
OfLong
{
final
Random
rng
;
long
index
;
final
long
fence
;
final
long
origin
;
final
long
bound
;
RandomLongsSpliterator
(
Random
rng
,
long
index
,
long
fence
,
long
origin
,
long
bound
)
{
this
.
rng
=
rng
;
this
.
index
=
index
;
this
.
fence
=
fence
;
this
.
origin
=
origin
;
this
.
bound
=
bound
;
}
public
RandomLongsSpliterator
trySplit
()
{
long
i
=
index
,
m
=
(
i
+
fence
)
>>>
1
;
return
(
m
<=
i
)
?
null
:
new
RandomLongsSpliterator
(
rng
,
i
,
index
=
m
,
origin
,
bound
);
}
public
long
estimateSize
()
{
return
fence
-
index
;
}
public
int
characteristics
()
{
return
(
Spliterator
.
SIZED
|
Spliterator
.
SUBSIZED
|
Spliterator
.
NONNULL
|
Spliterator
.
IMMUTABLE
);
}
public
boolean
tryAdvance
(
LongConsumer
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
consumer
.
accept
(
rng
.
internalNextLong
(
origin
,
bound
));
index
=
i
+
1
;
return
true
;
}
return
false
;
}
public
void
forEachRemaining
(
LongConsumer
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
index
=
f
;
Random
r
=
rng
;
long
o
=
origin
,
b
=
bound
;
do
{
consumer
.
accept
(
r
.
internalNextLong
(
o
,
b
));
}
while
(++
i
<
f
);
}
}
}
/**
* Spliterator for double streams.
*/
static
final
class
RandomDoublesSpliterator
implements
Spliterator
.
OfDouble
{
final
Random
rng
;
long
index
;
final
long
fence
;
final
double
origin
;
final
double
bound
;
RandomDoublesSpliterator
(
Random
rng
,
long
index
,
long
fence
,
double
origin
,
double
bound
)
{
this
.
rng
=
rng
;
this
.
index
=
index
;
this
.
fence
=
fence
;
this
.
origin
=
origin
;
this
.
bound
=
bound
;
}
public
RandomDoublesSpliterator
trySplit
()
{
long
i
=
index
,
m
=
(
i
+
fence
)
>>>
1
;
return
(
m
<=
i
)
?
null
:
new
RandomDoublesSpliterator
(
rng
,
i
,
index
=
m
,
origin
,
bound
);
}
public
long
estimateSize
()
{
return
fence
-
index
;
}
public
int
characteristics
()
{
return
(
Spliterator
.
SIZED
|
Spliterator
.
SUBSIZED
|
Spliterator
.
NONNULL
|
Spliterator
.
IMMUTABLE
);
}
public
boolean
tryAdvance
(
DoubleConsumer
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
consumer
.
accept
(
rng
.
internalNextDouble
(
origin
,
bound
));
index
=
i
+
1
;
return
true
;
}
return
false
;
}
public
void
forEachRemaining
(
DoubleConsumer
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
index
=
f
;
Random
r
=
rng
;
double
o
=
origin
,
b
=
bound
;
do
{
consumer
.
accept
(
r
.
internalNextDouble
(
o
,
b
));
}
while
(++
i
<
f
);
}
}
}
/**
...
...
src/share/classes/java/util/SplittableRandom.java
0 → 100644
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
java.util
;
import
java.security.SecureRandom
;
import
java.net.InetAddress
;
import
java.util.concurrent.atomic.AtomicLong
;
import
java.util.function.IntConsumer
;
import
java.util.function.LongConsumer
;
import
java.util.function.DoubleConsumer
;
import
java.util.stream.StreamSupport
;
import
java.util.stream.IntStream
;
import
java.util.stream.LongStream
;
import
java.util.stream.DoubleStream
;
/**
* A generator of uniform pseudorandom values applicable for use in
* (among other contexts) isolated parallel computations that may
* generate subtasks. Class {@code SplittableRandom} supports methods for
* producing pseudorandom numbers of type {@code int}, {@code long},
* and {@code double} with similar usages as for class
* {@link java.util.Random} but differs in the following ways:
*
* <ul>
*
* <li>Series of generated values pass the DieHarder suite testing
* independence and uniformity properties of random number generators.
* (Most recently validated with <a
* href="http://www.phy.duke.edu/~rgb/General/dieharder.php"> version
* 3.31.1</a>.) These tests validate only the methods for certain
* types and ranges, but similar properties are expected to hold, at
* least approximately, for others as well. The <em>period</em>
* (length of any series of generated values before it repeats) is at
* least 2<sup>64</sup>. </li>
*
* <li> Method {@link #split} constructs and returns a new
* SplittableRandom instance that shares no mutable state with the
* current instance. However, with very high probability, the
* values collectively generated by the two objects have the same
* statistical properties as if the same quantity of values were
* generated by a single thread using a single {@code
* SplittableRandom} object. </li>
*
* <li>Instances of SplittableRandom are <em>not</em> thread-safe.
* They are designed to be split, not shared, across threads. For
* example, a {@link java.util.concurrent.ForkJoinTask
* fork/join-style} computation using random numbers might include a
* construction of the form {@code new
* Subtask(aSplittableRandom.split()).fork()}.
*
* <li>This class provides additional methods for generating random
* streams, that employ the above techniques when used in {@code
* stream.parallel()} mode.</li>
*
* </ul>
*
* <p>Instances of {@code SplittableRandom} are not cryptographically
* secure. Consider instead using {@link java.security.SecureRandom}
* in security-sensitive applications. Additionally,
* default-constructed instances do not use a cryptographically random
* seed unless the {@linkplain System#getProperty system property}
* {@code java.util.secureRandomSeed} is set to {@code true}.
*
* @author Guy Steele
* @author Doug Lea
* @since 1.8
*/
public
final
class
SplittableRandom
{
/*
* Implementation Overview.
*
* This algorithm was inspired by the "DotMix" algorithm by
* Leiserson, Schardl, and Sukha "Deterministic Parallel
* Random-Number Generation for Dynamic-Multithreading Platforms",
* PPoPP 2012, as well as those in "Parallel random numbers: as
* easy as 1, 2, 3" by Salmon, Morae, Dror, and Shaw, SC 2011. It
* differs mainly in simplifying and cheapening operations.
*
* The primary update step (method nextSeed()) is to add a
* constant ("gamma") to the current (64 bit) seed, forming a
* simple sequence. The seed and the gamma values for any two
* SplittableRandom instances are highly likely to be different.
*
* Methods nextLong, nextInt, and derivatives do not return the
* sequence (seed) values, but instead a hash-like bit-mix of
* their bits, producing more independently distributed sequences.
* For nextLong, the mix64 bit-mixing function computes the same
* value as the "64-bit finalizer" function in Austin Appleby's
* MurmurHash3 algorithm. See
* http://code.google.com/p/smhasher/wiki/MurmurHash3 , which
* comments: "The constants for the finalizers were generated by a
* simple simulated-annealing algorithm, and both avalanche all
* bits of 'h' to within 0.25% bias." The mix32 function is
* equivalent to (int)(mix64(seed) >>> 32), but faster because it
* omits a step that doesn't contribute to result.
*
* The split operation uses the current generator to form the seed
* and gamma for another SplittableRandom. To conservatively
* avoid potential correlations between seed and value generation,
* gamma selection (method nextGamma) uses the "Mix13" constants
* for MurmurHash3 described by David Stafford
* (http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html)
* To avoid potential weaknesses in bit-mixing transformations, we
* restrict gammas to odd values with at least 12 and no more than
* 52 bits set. Rather than rejecting candidates with too few or
* too many bits set, method nextGamma flips some bits (which has
* the effect of mapping at most 4 to any given gamma value).
* This reduces the effective set of 64bit odd gamma values by
* about 2<sup>14</sup>, a very tiny percentage, and serves as an
* automated screening for sequence constant selection that is
* left as an empirical decision in some other hashing and crypto
* algorithms.
*
* The resulting generator thus transforms a sequence in which
* (typically) many bits change on each step, with an inexpensive
* mixer with good (but less than cryptographically secure)
* avalanching.
*
* The default (no-argument) constructor, in essence, invokes
* split() for a common "seeder" SplittableRandom. Unlike other
* cases, this split must be performed in a thread-safe manner, so
* we use an AtomicLong to represent the seed rather than use an
* explicit SplittableRandom. To bootstrap the seeder, we start
* off using a seed based on current time and host unless the
* java.util.secureRandomSeed property is set. This serves as a
* slimmed-down (and insecure) variant of SecureRandom that also
* avoids stalls that may occur when using /dev/random.
*
* It is a relatively simple matter to apply the basic design here
* to use 128 bit seeds. However, emulating 128bit arithmetic and
* carrying around twice the state add more overhead than appears
* warranted for current usages.
*
* File organization: First the non-public methods that constitute
* the main algorithm, then the main public methods, followed by
* some custom spliterator classes needed for stream methods.
*/
/**
* The initial gamma value for (unsplit) SplittableRandoms. Must
* be odd with at least 12 and no more than 52 bits set. Currently
* set to the golden ratio scaled to 64bits.
*/
private
static
final
long
INITIAL_GAMMA
=
0x9e3779b97f4a7c15
L
;
/**
* The least non-zero value returned by nextDouble(). This value
* is scaled by a random value of 53 bits to produce a result.
*/
private
static
final
double
DOUBLE_UNIT
=
1.0
/
(
1L
<<
53
);
/**
* The seed. Updated only via method nextSeed.
*/
private
long
seed
;
/**
* The step value.
*/
private
final
long
gamma
;
/**
* Internal constructor used by all others except default constructor.
*/
private
SplittableRandom
(
long
seed
,
long
gamma
)
{
this
.
seed
=
seed
;
this
.
gamma
=
gamma
;
}
/**
* Computes MurmurHash3 64bit mix function.
*/
private
static
long
mix64
(
long
z
)
{
z
=
(
z
^
(
z
>>>
33
))
*
0xff51afd7ed558ccd
L
;
z
=
(
z
^
(
z
>>>
33
))
*
0xc4ceb9fe1a85ec53
L
;
return
z
^
(
z
>>>
33
);
}
/**
* Returns the 32 high bits of mix64(z) as int.
*/
private
static
int
mix32
(
long
z
)
{
z
=
(
z
^
(
z
>>>
33
))
*
0xff51afd7ed558ccd
L
;
return
(
int
)(((
z
^
(
z
>>>
33
))
*
0xc4ceb9fe1a85ec53
L
)
>>>
32
);
}
/**
* Returns the gamma value to use for a new split instance.
*/
private
static
long
nextGamma
(
long
z
)
{
z
=
(
z
^
(
z
>>>
30
))
*
0xbf58476d1ce4e5b9
L
;
// Stafford "Mix13"
z
=
(
z
^
(
z
>>>
27
))
*
0x94d049bb133111eb
L
;
z
=
(
z
^
(
z
>>>
31
))
|
1L
;
// force to be odd
int
n
=
Long
.
bitCount
(
z
);
// ensure enough 0 and 1 bits
return
(
n
<
12
||
n
>
52
)
?
z
^
0xaaaaaaaaaaaaaaaa
L
:
z
;
}
/**
* Adds gamma to seed.
*/
private
long
nextSeed
()
{
return
seed
+=
gamma
;
}
/**
* The seed generator for default constructors.
*/
private
static
final
AtomicLong
seeder
=
new
AtomicLong
(
initialSeed
());
private
static
long
initialSeed
()
{
String
pp
=
java
.
security
.
AccessController
.
doPrivileged
(
new
sun
.
security
.
action
.
GetPropertyAction
(
"java.util.secureRandomSeed"
));
if
(
pp
!=
null
&&
pp
.
equalsIgnoreCase
(
"true"
))
{
byte
[]
seedBytes
=
java
.
security
.
SecureRandom
.
getSeed
(
8
);
long
s
=
(
long
)(
seedBytes
[
0
])
&
0xff
L
;
for
(
int
i
=
1
;
i
<
8
;
++
i
)
s
=
(
s
<<
8
)
|
((
long
)(
seedBytes
[
i
])
&
0xff
L
);
return
s
;
}
int
hh
=
0
;
// hashed host address
try
{
hh
=
InetAddress
.
getLocalHost
().
hashCode
();
}
catch
(
Exception
ignore
)
{
}
return
(
mix64
((((
long
)
hh
)
<<
32
)
^
System
.
currentTimeMillis
())
^
mix64
(
System
.
nanoTime
()));
}
// IllegalArgumentException messages
static
final
String
BadBound
=
"bound must be positive"
;
static
final
String
BadRange
=
"bound must be greater than origin"
;
static
final
String
BadSize
=
"size must be non-negative"
;
/*
* Internal versions of nextX methods used by streams, as well as
* the public nextX(origin, bound) methods. These exist mainly to
* avoid the need for multiple versions of stream spliterators
* across the different exported forms of streams.
*/
/**
* The form of nextLong used by LongStream Spliterators. If
* origin is greater than bound, acts as unbounded form of
* nextLong, else as bounded form.
*
* @param origin the least value, unless greater than bound
* @param bound the upper bound (exclusive), must not equal origin
* @return a pseudorandom value
*/
final
long
internalNextLong
(
long
origin
,
long
bound
)
{
/*
* Four Cases:
*
* 1. If the arguments indicate unbounded form, act as
* nextLong().
*
* 2. If the range is an exact power of two, apply the
* associated bit mask.
*
* 3. If the range is positive, loop to avoid potential bias
* when the implicit nextLong() bound (2<sup>64</sup>) is not
* evenly divisible by the range. The loop rejects candidates
* computed from otherwise over-represented values. The
* expected number of iterations under an ideal generator
* varies from 1 to 2, depending on the bound. The loop itself
* takes an unlovable form. Because the first candidate is
* already available, we need a break-in-the-middle
* construction, which is concisely but cryptically performed
* within the while-condition of a body-less for loop.
*
* 4. Otherwise, the range cannot be represented as a positive
* long. The loop repeatedly generates unbounded longs until
* obtaining a candidate meeting constraints (with an expected
* number of iterations of less than two).
*/
long
r
=
mix64
(
nextSeed
());
if
(
origin
<
bound
)
{
long
n
=
bound
-
origin
,
m
=
n
-
1
;
if
((
n
&
m
)
==
0L
)
// power of two
r
=
(
r
&
m
)
+
origin
;
else
if
(
n
>
0L
)
{
// reject over-represented candidates
for
(
long
u
=
r
>>>
1
;
// ensure nonnegative
u
+
m
-
(
r
=
u
%
n
)
<
0L
;
// rejection check
u
=
mix64
(
nextSeed
())
>>>
1
)
// retry
;
r
+=
origin
;
}
else
{
// range not representable as long
while
(
r
<
origin
||
r
>=
bound
)
r
=
mix64
(
nextSeed
());
}
}
return
r
;
}
/**
* The form of nextInt used by IntStream Spliterators.
* Exactly the same as long version, except for types.
*
* @param origin the least value, unless greater than bound
* @param bound the upper bound (exclusive), must not equal origin
* @return a pseudorandom value
*/
final
int
internalNextInt
(
int
origin
,
int
bound
)
{
int
r
=
mix32
(
nextSeed
());
if
(
origin
<
bound
)
{
int
n
=
bound
-
origin
,
m
=
n
-
1
;
if
((
n
&
m
)
==
0
)
r
=
(
r
&
m
)
+
origin
;
else
if
(
n
>
0
)
{
for
(
int
u
=
r
>>>
1
;
u
+
m
-
(
r
=
u
%
n
)
<
0
;
u
=
mix32
(
nextSeed
())
>>>
1
)
;
r
+=
origin
;
}
else
{
while
(
r
<
origin
||
r
>=
bound
)
r
=
mix32
(
nextSeed
());
}
}
return
r
;
}
/**
* The form of nextDouble used by DoubleStream Spliterators.
*
* @param origin the least value, unless greater than bound
* @param bound the upper bound (exclusive), must not equal origin
* @return a pseudorandom value
*/
final
double
internalNextDouble
(
double
origin
,
double
bound
)
{
double
r
=
(
nextLong
()
>>>
11
)
*
DOUBLE_UNIT
;
if
(
origin
<
bound
)
{
r
=
r
*
(
bound
-
origin
)
+
origin
;
if
(
r
>=
bound
)
// correct for rounding
r
=
Double
.
longBitsToDouble
(
Double
.
doubleToLongBits
(
bound
)
-
1
);
}
return
r
;
}
/* ---------------- public methods ---------------- */
/**
* Creates a new SplittableRandom instance using the specified
* initial seed. SplittableRandom instances created with the same
* seed in the same program generate identical sequences of values.
*
* @param seed the initial seed
*/
public
SplittableRandom
(
long
seed
)
{
this
(
seed
,
INITIAL_GAMMA
);
}
/**
* Creates a new SplittableRandom instance that is likely to
* generate sequences of values that are statistically independent
* of those of any other instances in the current program; and
* may, and typically does, vary across program invocations.
*/
public
SplittableRandom
()
{
// emulate seeder.split()
this
.
gamma
=
nextGamma
(
this
.
seed
=
seeder
.
addAndGet
(
INITIAL_GAMMA
));
}
/**
* Constructs and returns a new SplittableRandom instance that
* shares no mutable state with this instance. However, with very
* high probability, the set of values collectively generated by
* the two objects has the same statistical properties as if the
* same quantity of values were generated by a single thread using
* a single SplittableRandom object. Either or both of the two
* objects may be further split using the {@code split()} method,
* and the same expected statistical properties apply to the
* entire set of generators constructed by such recursive
* splitting.
*
* @return the new SplittableRandom instance
*/
public
SplittableRandom
split
()
{
long
s
=
nextSeed
();
return
new
SplittableRandom
(
s
,
nextGamma
(
s
));
}
/**
* Returns a pseudorandom {@code int} value.
*
* @return a pseudorandom {@code int} value
*/
public
int
nextInt
()
{
return
mix32
(
nextSeed
());
}
/**
* Returns a pseudorandom {@code int} value between zero (inclusive)
* and the specified bound (exclusive).
*
* @param bound the upper bound (exclusive). Must be positive.
* @return a pseudorandom {@code int} value between zero
* (inclusive) and the bound (exclusive)
* @throws IllegalArgumentException if {@code bound} is not positive
*/
public
int
nextInt
(
int
bound
)
{
if
(
bound
<=
0
)
throw
new
IllegalArgumentException
(
BadBound
);
// Specialize internalNextInt for origin 0
int
r
=
mix32
(
nextSeed
());
int
m
=
bound
-
1
;
if
((
bound
&
m
)
==
0
)
// power of two
r
&=
m
;
else
{
// reject over-represented candidates
for
(
int
u
=
r
>>>
1
;
u
+
m
-
(
r
=
u
%
bound
)
<
0
;
u
=
mix32
(
nextSeed
())
>>>
1
)
;
}
return
r
;
}
/**
* Returns a pseudorandom {@code int} value between the specified
* origin (inclusive) and the specified bound (exclusive).
*
* @param origin the least value returned
* @param bound the upper bound (exclusive)
* @return a pseudorandom {@code int} value between the origin
* (inclusive) and the bound (exclusive)
* @throws IllegalArgumentException if {@code origin} is greater than
* or equal to {@code bound}
*/
public
int
nextInt
(
int
origin
,
int
bound
)
{
if
(
origin
>=
bound
)
throw
new
IllegalArgumentException
(
BadRange
);
return
internalNextInt
(
origin
,
bound
);
}
/**
* Returns a pseudorandom {@code long} value.
*
* @return a pseudorandom {@code long} value
*/
public
long
nextLong
()
{
return
mix64
(
nextSeed
());
}
/**
* Returns a pseudorandom {@code long} value between zero (inclusive)
* and the specified bound (exclusive).
*
* @param bound the upper bound (exclusive). Must be positive.
* @return a pseudorandom {@code long} value between zero
* (inclusive) and the bound (exclusive)
* @throws IllegalArgumentException if {@code bound} is not positive
*/
public
long
nextLong
(
long
bound
)
{
if
(
bound
<=
0
)
throw
new
IllegalArgumentException
(
BadBound
);
// Specialize internalNextLong for origin 0
long
r
=
mix64
(
nextSeed
());
long
m
=
bound
-
1
;
if
((
bound
&
m
)
==
0L
)
// power of two
r
&=
m
;
else
{
// reject over-represented candidates
for
(
long
u
=
r
>>>
1
;
u
+
m
-
(
r
=
u
%
bound
)
<
0L
;
u
=
mix64
(
nextSeed
())
>>>
1
)
;
}
return
r
;
}
/**
* Returns a pseudorandom {@code long} value between the specified
* origin (inclusive) and the specified bound (exclusive).
*
* @param origin the least value returned
* @param bound the upper bound (exclusive)
* @return a pseudorandom {@code long} value between the origin
* (inclusive) and the bound (exclusive)
* @throws IllegalArgumentException if {@code origin} is greater than
* or equal to {@code bound}
*/
public
long
nextLong
(
long
origin
,
long
bound
)
{
if
(
origin
>=
bound
)
throw
new
IllegalArgumentException
(
BadRange
);
return
internalNextLong
(
origin
,
bound
);
}
/**
* Returns a pseudorandom {@code double} value between zero
* (inclusive) and one (exclusive).
*
* @return a pseudorandom {@code double} value between zero
* (inclusive) and one (exclusive)
*/
public
double
nextDouble
()
{
return
(
mix64
(
nextSeed
())
>>>
11
)
*
DOUBLE_UNIT
;
}
/**
* Returns a pseudorandom {@code double} value between 0.0
* (inclusive) and the specified bound (exclusive).
*
* @param bound the upper bound (exclusive). Must be positive.
* @return a pseudorandom {@code double} value between zero
* (inclusive) and the bound (exclusive)
* @throws IllegalArgumentException if {@code bound} is not positive
*/
public
double
nextDouble
(
double
bound
)
{
if
(!(
bound
>
0.0
))
throw
new
IllegalArgumentException
(
BadBound
);
double
result
=
(
mix64
(
nextSeed
())
>>>
11
)
*
DOUBLE_UNIT
*
bound
;
return
(
result
<
bound
)
?
result
:
// correct for rounding
Double
.
longBitsToDouble
(
Double
.
doubleToLongBits
(
bound
)
-
1
);
}
/**
* Returns a pseudorandom {@code double} value between the specified
* origin (inclusive) and bound (exclusive).
*
* @param origin the least value returned
* @param bound the upper bound (exclusive)
* @return a pseudorandom {@code double} value between the origin
* (inclusive) and the bound (exclusive)
* @throws IllegalArgumentException if {@code origin} is greater than
* or equal to {@code bound}
*/
public
double
nextDouble
(
double
origin
,
double
bound
)
{
if
(!(
origin
<
bound
))
throw
new
IllegalArgumentException
(
BadRange
);
return
internalNextDouble
(
origin
,
bound
);
}
/**
* Returns a pseudorandom {@code boolean} value.
*
* @return a pseudorandom {@code boolean} value
*/
public
boolean
nextBoolean
()
{
return
mix32
(
nextSeed
())
<
0
;
}
// stream methods, coded in a way intended to better isolate for
// maintenance purposes the small differences across forms.
/**
* Returns a stream producing the given {@code streamSize} number
* of pseudorandom {@code int} values from this generator and/or
* one split from it.
*
* @param streamSize the number of values to generate
* @return a stream of pseudorandom {@code int} values
* @throws IllegalArgumentException if {@code streamSize} is
* less than zero
*/
public
IntStream
ints
(
long
streamSize
)
{
if
(
streamSize
<
0L
)
throw
new
IllegalArgumentException
(
BadSize
);
return
StreamSupport
.
intStream
(
new
RandomIntsSpliterator
(
this
,
0L
,
streamSize
,
Integer
.
MAX_VALUE
,
0
),
false
);
}
/**
* Returns an effectively unlimited stream of pseudorandom {@code int}
* values from this generator and/or one split from it.
*
* @implNote This method is implemented to be equivalent to {@code
* ints(Long.MAX_VALUE)}.
*
* @return a stream of pseudorandom {@code int} values
*/
public
IntStream
ints
()
{
return
StreamSupport
.
intStream
(
new
RandomIntsSpliterator
(
this
,
0L
,
Long
.
MAX_VALUE
,
Integer
.
MAX_VALUE
,
0
),
false
);
}
/**
* Returns a stream producing the given {@code streamSize} number
* of pseudorandom {@code int} values from this generator and/or one split
* from it; each value conforms to the given origin (inclusive) and bound
* (exclusive).
*
* @param streamSize the number of values to generate
* @param randomNumberOrigin the origin (inclusive) of each random value
* @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code int} values,
* each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException if {@code streamSize} is
* less than zero, or {@code randomNumberOrigin}
* is greater than or equal to {@code randomNumberBound}
*/
public
IntStream
ints
(
long
streamSize
,
int
randomNumberOrigin
,
int
randomNumberBound
)
{
if
(
streamSize
<
0L
)
throw
new
IllegalArgumentException
(
BadSize
);
if
(
randomNumberOrigin
>=
randomNumberBound
)
throw
new
IllegalArgumentException
(
BadRange
);
return
StreamSupport
.
intStream
(
new
RandomIntsSpliterator
(
this
,
0L
,
streamSize
,
randomNumberOrigin
,
randomNumberBound
),
false
);
}
/**
* Returns an effectively unlimited stream of pseudorandom {@code
* int} values from this generator and/or one split from it; each value
* conforms to the given origin (inclusive) and bound (exclusive).
*
* @implNote This method is implemented to be equivalent to {@code
* ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
*
* @param randomNumberOrigin the origin (inclusive) of each random value
* @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code int} values,
* each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException if {@code randomNumberOrigin}
* is greater than or equal to {@code randomNumberBound}
*/
public
IntStream
ints
(
int
randomNumberOrigin
,
int
randomNumberBound
)
{
if
(
randomNumberOrigin
>=
randomNumberBound
)
throw
new
IllegalArgumentException
(
BadRange
);
return
StreamSupport
.
intStream
(
new
RandomIntsSpliterator
(
this
,
0L
,
Long
.
MAX_VALUE
,
randomNumberOrigin
,
randomNumberBound
),
false
);
}
/**
* Returns a stream producing the given {@code streamSize} number
* of pseudorandom {@code long} values from this generator and/or
* one split from it.
*
* @param streamSize the number of values to generate
* @return a stream of pseudorandom {@code long} values
* @throws IllegalArgumentException if {@code streamSize} is
* less than zero
*/
public
LongStream
longs
(
long
streamSize
)
{
if
(
streamSize
<
0L
)
throw
new
IllegalArgumentException
(
BadSize
);
return
StreamSupport
.
longStream
(
new
RandomLongsSpliterator
(
this
,
0L
,
streamSize
,
Long
.
MAX_VALUE
,
0L
),
false
);
}
/**
* Returns an effectively unlimited stream of pseudorandom {@code
* long} values from this generator and/or one split from it.
*
* @implNote This method is implemented to be equivalent to {@code
* longs(Long.MAX_VALUE)}.
*
* @return a stream of pseudorandom {@code long} values
*/
public
LongStream
longs
()
{
return
StreamSupport
.
longStream
(
new
RandomLongsSpliterator
(
this
,
0L
,
Long
.
MAX_VALUE
,
Long
.
MAX_VALUE
,
0L
),
false
);
}
/**
* Returns a stream producing the given {@code streamSize} number of
* pseudorandom {@code long} values from this generator and/or one split
* from it; each value conforms to the given origin (inclusive) and bound
* (exclusive).
*
* @param streamSize the number of values to generate
* @param randomNumberOrigin the origin (inclusive) of each random value
* @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code long} values,
* each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException if {@code streamSize} is
* less than zero, or {@code randomNumberOrigin}
* is greater than or equal to {@code randomNumberBound}
*/
public
LongStream
longs
(
long
streamSize
,
long
randomNumberOrigin
,
long
randomNumberBound
)
{
if
(
streamSize
<
0L
)
throw
new
IllegalArgumentException
(
BadSize
);
if
(
randomNumberOrigin
>=
randomNumberBound
)
throw
new
IllegalArgumentException
(
BadRange
);
return
StreamSupport
.
longStream
(
new
RandomLongsSpliterator
(
this
,
0L
,
streamSize
,
randomNumberOrigin
,
randomNumberBound
),
false
);
}
/**
* Returns an effectively unlimited stream of pseudorandom {@code
* long} values from this generator and/or one split from it; each value
* conforms to the given origin (inclusive) and bound (exclusive).
*
* @implNote This method is implemented to be equivalent to {@code
* longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
*
* @param randomNumberOrigin the origin (inclusive) of each random value
* @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code long} values,
* each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException if {@code randomNumberOrigin}
* is greater than or equal to {@code randomNumberBound}
*/
public
LongStream
longs
(
long
randomNumberOrigin
,
long
randomNumberBound
)
{
if
(
randomNumberOrigin
>=
randomNumberBound
)
throw
new
IllegalArgumentException
(
BadRange
);
return
StreamSupport
.
longStream
(
new
RandomLongsSpliterator
(
this
,
0L
,
Long
.
MAX_VALUE
,
randomNumberOrigin
,
randomNumberBound
),
false
);
}
/**
* Returns a stream producing the given {@code streamSize} number of
* pseudorandom {@code double} values from this generator and/or one split
* from it; each value is between zero (inclusive) and one (exclusive).
*
* @param streamSize the number of values to generate
* @return a stream of {@code double} values
* @throws IllegalArgumentException if {@code streamSize} is
* less than zero
*/
public
DoubleStream
doubles
(
long
streamSize
)
{
if
(
streamSize
<
0L
)
throw
new
IllegalArgumentException
(
BadSize
);
return
StreamSupport
.
doubleStream
(
new
RandomDoublesSpliterator
(
this
,
0L
,
streamSize
,
Double
.
MAX_VALUE
,
0.0
),
false
);
}
/**
* Returns an effectively unlimited stream of pseudorandom {@code
* double} values from this generator and/or one split from it; each value
* is between zero (inclusive) and one (exclusive).
*
* @implNote This method is implemented to be equivalent to {@code
* doubles(Long.MAX_VALUE)}.
*
* @return a stream of pseudorandom {@code double} values
*/
public
DoubleStream
doubles
()
{
return
StreamSupport
.
doubleStream
(
new
RandomDoublesSpliterator
(
this
,
0L
,
Long
.
MAX_VALUE
,
Double
.
MAX_VALUE
,
0.0
),
false
);
}
/**
* Returns a stream producing the given {@code streamSize} number of
* pseudorandom {@code double} values from this generator and/or one split
* from it; each value conforms to the given origin (inclusive) and bound
* (exclusive).
*
* @param streamSize the number of values to generate
* @param randomNumberOrigin the origin (inclusive) of each random value
* @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code double} values,
* each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException if {@code streamSize} is
* less than zero
* @throws IllegalArgumentException if {@code randomNumberOrigin}
* is greater than or equal to {@code randomNumberBound}
*/
public
DoubleStream
doubles
(
long
streamSize
,
double
randomNumberOrigin
,
double
randomNumberBound
)
{
if
(
streamSize
<
0L
)
throw
new
IllegalArgumentException
(
BadSize
);
if
(!(
randomNumberOrigin
<
randomNumberBound
))
throw
new
IllegalArgumentException
(
BadRange
);
return
StreamSupport
.
doubleStream
(
new
RandomDoublesSpliterator
(
this
,
0L
,
streamSize
,
randomNumberOrigin
,
randomNumberBound
),
false
);
}
/**
* Returns an effectively unlimited stream of pseudorandom {@code
* double} values from this generator and/or one split from it; each value
* conforms to the given origin (inclusive) and bound (exclusive).
*
* @implNote This method is implemented to be equivalent to {@code
* doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
*
* @param randomNumberOrigin the origin (inclusive) of each random value
* @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code double} values,
* each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException if {@code randomNumberOrigin}
* is greater than or equal to {@code randomNumberBound}
*/
public
DoubleStream
doubles
(
double
randomNumberOrigin
,
double
randomNumberBound
)
{
if
(!(
randomNumberOrigin
<
randomNumberBound
))
throw
new
IllegalArgumentException
(
BadRange
);
return
StreamSupport
.
doubleStream
(
new
RandomDoublesSpliterator
(
this
,
0L
,
Long
.
MAX_VALUE
,
randomNumberOrigin
,
randomNumberBound
),
false
);
}
/**
* Spliterator for int streams. We multiplex the four int
* versions into one class by treating a bound less than origin as
* unbounded, and also by treating "infinite" as equivalent to
* Long.MAX_VALUE. For splits, it uses the standard divide-by-two
* approach. The long and double versions of this class are
* identical except for types.
*/
static
final
class
RandomIntsSpliterator
implements
Spliterator
.
OfInt
{
final
SplittableRandom
rng
;
long
index
;
final
long
fence
;
final
int
origin
;
final
int
bound
;
RandomIntsSpliterator
(
SplittableRandom
rng
,
long
index
,
long
fence
,
int
origin
,
int
bound
)
{
this
.
rng
=
rng
;
this
.
index
=
index
;
this
.
fence
=
fence
;
this
.
origin
=
origin
;
this
.
bound
=
bound
;
}
public
RandomIntsSpliterator
trySplit
()
{
long
i
=
index
,
m
=
(
i
+
fence
)
>>>
1
;
return
(
m
<=
i
)
?
null
:
new
RandomIntsSpliterator
(
rng
.
split
(),
i
,
index
=
m
,
origin
,
bound
);
}
public
long
estimateSize
()
{
return
fence
-
index
;
}
public
int
characteristics
()
{
return
(
Spliterator
.
SIZED
|
Spliterator
.
SUBSIZED
|
Spliterator
.
NONNULL
|
Spliterator
.
IMMUTABLE
);
}
public
boolean
tryAdvance
(
IntConsumer
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
consumer
.
accept
(
rng
.
internalNextInt
(
origin
,
bound
));
index
=
i
+
1
;
return
true
;
}
return
false
;
}
public
void
forEachRemaining
(
IntConsumer
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
index
=
f
;
SplittableRandom
r
=
rng
;
int
o
=
origin
,
b
=
bound
;
do
{
consumer
.
accept
(
r
.
internalNextInt
(
o
,
b
));
}
while
(++
i
<
f
);
}
}
}
/**
* Spliterator for long streams.
*/
static
final
class
RandomLongsSpliterator
implements
Spliterator
.
OfLong
{
final
SplittableRandom
rng
;
long
index
;
final
long
fence
;
final
long
origin
;
final
long
bound
;
RandomLongsSpliterator
(
SplittableRandom
rng
,
long
index
,
long
fence
,
long
origin
,
long
bound
)
{
this
.
rng
=
rng
;
this
.
index
=
index
;
this
.
fence
=
fence
;
this
.
origin
=
origin
;
this
.
bound
=
bound
;
}
public
RandomLongsSpliterator
trySplit
()
{
long
i
=
index
,
m
=
(
i
+
fence
)
>>>
1
;
return
(
m
<=
i
)
?
null
:
new
RandomLongsSpliterator
(
rng
.
split
(),
i
,
index
=
m
,
origin
,
bound
);
}
public
long
estimateSize
()
{
return
fence
-
index
;
}
public
int
characteristics
()
{
return
(
Spliterator
.
SIZED
|
Spliterator
.
SUBSIZED
|
Spliterator
.
NONNULL
|
Spliterator
.
IMMUTABLE
);
}
public
boolean
tryAdvance
(
LongConsumer
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
consumer
.
accept
(
rng
.
internalNextLong
(
origin
,
bound
));
index
=
i
+
1
;
return
true
;
}
return
false
;
}
public
void
forEachRemaining
(
LongConsumer
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
index
=
f
;
SplittableRandom
r
=
rng
;
long
o
=
origin
,
b
=
bound
;
do
{
consumer
.
accept
(
r
.
internalNextLong
(
o
,
b
));
}
while
(++
i
<
f
);
}
}
}
/**
* Spliterator for double streams.
*/
static
final
class
RandomDoublesSpliterator
implements
Spliterator
.
OfDouble
{
final
SplittableRandom
rng
;
long
index
;
final
long
fence
;
final
double
origin
;
final
double
bound
;
RandomDoublesSpliterator
(
SplittableRandom
rng
,
long
index
,
long
fence
,
double
origin
,
double
bound
)
{
this
.
rng
=
rng
;
this
.
index
=
index
;
this
.
fence
=
fence
;
this
.
origin
=
origin
;
this
.
bound
=
bound
;
}
public
RandomDoublesSpliterator
trySplit
()
{
long
i
=
index
,
m
=
(
i
+
fence
)
>>>
1
;
return
(
m
<=
i
)
?
null
:
new
RandomDoublesSpliterator
(
rng
.
split
(),
i
,
index
=
m
,
origin
,
bound
);
}
public
long
estimateSize
()
{
return
fence
-
index
;
}
public
int
characteristics
()
{
return
(
Spliterator
.
SIZED
|
Spliterator
.
SUBSIZED
|
Spliterator
.
NONNULL
|
Spliterator
.
IMMUTABLE
);
}
public
boolean
tryAdvance
(
DoubleConsumer
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
consumer
.
accept
(
rng
.
internalNextDouble
(
origin
,
bound
));
index
=
i
+
1
;
return
true
;
}
return
false
;
}
public
void
forEachRemaining
(
DoubleConsumer
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
index
=
f
;
SplittableRandom
r
=
rng
;
double
o
=
origin
,
b
=
bound
;
do
{
consumer
.
accept
(
r
.
internalNextDouble
(
o
,
b
));
}
while
(++
i
<
f
);
}
}
}
}
src/share/classes/java/util/TimSort.java
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright 2009 Google Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
...
...
@@ -176,7 +177,7 @@ class TimSort<T> {
*/
int
stackLen
=
(
len
<
120
?
5
:
len
<
1542
?
10
:
len
<
119151
?
19
:
40
);
len
<
119151
?
24
:
40
);
runBase
=
new
int
[
stackLen
];
runLen
=
new
int
[
stackLen
];
}
...
...
src/share/classes/java/util/TreeMap.java
浏览文件 @
f9ad02d9
...
...
@@ -972,6 +972,27 @@ public class TreeMap<K,V>
return
tailMap
(
fromKey
,
true
);
}
@Override
public
boolean
replace
(
K
key
,
V
oldValue
,
V
newValue
)
{
Entry
<
K
,
V
>
p
=
getEntry
(
key
);
if
(
p
!=
null
&&
Objects
.
equals
(
oldValue
,
p
.
value
))
{
p
.
value
=
newValue
;
return
true
;
}
return
false
;
}
@Override
public
V
replace
(
K
key
,
V
value
)
{
Entry
<
K
,
V
>
p
=
getEntry
(
key
);
if
(
p
!=
null
)
{
V
oldValue
=
p
.
value
;
p
.
value
=
value
;
return
oldValue
;
}
return
null
;
}
@Override
public
void
forEach
(
BiConsumer
<?
super
K
,
?
super
V
>
action
)
{
Objects
.
requireNonNull
(
action
);
...
...
src/share/classes/java/util/concurrent/ThreadLocalRandom.java
浏览文件 @
f9ad02d9
...
...
@@ -37,11 +37,16 @@ package java.util.concurrent;
import
java.io.ObjectStreamField
;
import
java.util.Random
;
import
java.util.Spliterator
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.concurrent.atomic.AtomicLong
;
import
java.util.function.DoubleConsumer
;
import
java.util.function.IntConsumer
;
import
java.util.function.LongConsumer
;
import
java.util.stream.DoubleStream
;
import
java.util.stream.IntStream
;
import
java.util.stream.LongStream
;
import
java.util.stream.StreamSupport
;
/**
* A random number generator isolated to the current thread. Like the
...
...
@@ -64,6 +69,10 @@ import java.util.stream.LongStream;
* <p>This class also provides additional commonly used bounded random
* generation methods.
*
* <p>Instances of {@code ThreadLocalRandom} are not cryptographically
* secure. Consider instead using {@link java.security.SecureRandom}
* in security-sensitive applications.
*
* @since 1.7
* @author Doug Lea
*/
...
...
@@ -85,28 +94,26 @@ public class ThreadLocalRandom extends Random {
* application-level overhead and footprint of most concurrent
* programs.
*
* Even though this class subclasses java.util.Random, it uses the
* same basic algorithm as java.util.SplittableRandom. (See its
* internal documentation for explanations, which are not repeated
* here.) Because ThreadLocalRandoms are not splittable
* though, we use only a single 64bit gamma.
*
* Because this class is in a different package than class Thread,
* field access methods use Unsafe to bypass access control rules.
* The base functionality of Random methods is conveniently
* isolated in method next(bits), that just reads and writes the
* Thread field rather than its own field. However, to conform to
* the requirements of the Random superclass constructor, the
* common static ThreadLocalRandom maintains an "initialized"
* field for the sake of rejecting user calls to setSeed while
* still allowing a call from constructor. Note that
* serialization is completely unnecessary because there is only a
* static singleton. But we generate a serial form containing
* "rnd" and "initialized" fields to ensure compatibility across
* versions.
*
* Per-thread initialization is similar to that in the no-arg
* Random constructor, but we avoid correlation among not only
* initial seeds of those created in different threads, but also
* those created using class Random itself; while at the same time
* not changing any statistical properties. So we use the same
* underlying multiplicative sequence, but start the sequence far
* away from the base version, and then merge (xor) current time
* and per-thread probe bits to generate initial values.
* To conform to the requirements of the Random superclass
* constructor, the common static ThreadLocalRandom maintains an
* "initialized" field for the sake of rejecting user calls to
* setSeed while still allowing a call from constructor. Note
* that serialization is completely unnecessary because there is
* only a static singleton. But we generate a serial form
* containing "rnd" and "initialized" fields to ensure
* compatibility across versions.
*
* Implementations of non-core methods are mostly the same as in
* SplittableRandom, that were in part derived from a previous
* version of this class.
*
* The nextLocalGaussian ThreadLocal supports the very rarely used
* nextGaussian method by providing a holder for the second of a
...
...
@@ -115,24 +122,51 @@ public class ThreadLocalRandom extends Random {
* but we provide identical statistical properties.
*/
// same constants as Random, but must be redeclared because private
private
static
final
long
multiplier
=
0x5DEECE66D
L
;
private
static
final
long
addend
=
0xB
L
;
private
static
final
long
mask
=
(
1L
<<
48
)
-
1
;
private
static
final
int
PROBE_INCREMENT
=
0x61c88647
;
/** Generates the basis for per-thread initial seed values */
private
static
final
AtomicLong
seedGenerator
=
new
AtomicLong
(
1269533684904616924L
);
/** Generates per-thread initialization/probe field */
private
static
final
AtomicInteger
probeGenerator
=
new
AtomicInteger
(
0xe80f8647
);
new
AtomicInteger
();
/**
* The next seed for default constructors.
*/
private
static
final
AtomicLong
seeder
=
new
AtomicLong
(
mix64
(
System
.
currentTimeMillis
())
^
mix64
(
System
.
nanoTime
()));
/**
* The seed increment
*/
private
static
final
long
GAMMA
=
0x9e3779b97f4a7c15
L
;
/**
* The increment for generating probe values
*/
private
static
final
int
PROBE_INCREMENT
=
0x9e3779b9
;
/**
* The increment of seeder per new instance
*/
private
static
final
long
SEEDER_INCREMENT
=
0xbb67ae8584caa73b
L
;
// Constants from SplittableRandom
private
static
final
double
DOUBLE_UNIT
=
1.0
/
(
1L
<<
53
);
private
static
final
float
FLOAT_UNIT
=
1.0f
/
(
1
<<
24
);
/** Rarely-used holder for the second of a pair of Gaussians */
private
static
final
ThreadLocal
<
Double
>
nextLocalGaussian
=
new
ThreadLocal
<
Double
>();
private
static
long
mix64
(
long
z
)
{
z
=
(
z
^
(
z
>>>
33
))
*
0xff51afd7ed558ccd
L
;
z
=
(
z
^
(
z
>>>
33
))
*
0xc4ceb9fe1a85ec53
L
;
return
z
^
(
z
>>>
33
);
}
private
static
int
mix32
(
long
z
)
{
z
=
(
z
^
(
z
>>>
33
))
*
0xff51afd7ed558ccd
L
;
return
(
int
)(((
z
^
(
z
>>>
33
))
*
0xc4ceb9fe1a85ec53
L
)
>>>
32
);
}
/**
* Field used only during singleton initialization.
* True when constructor completes.
...
...
@@ -155,16 +189,11 @@ public class ThreadLocalRandom extends Random {
* rely on (static) atomic generators to initialize the values.
*/
static
final
void
localInit
()
{
int
p
=
probeGenerator
.
getAndAdd
(
PROBE_INCREMENT
);
int
p
=
probeGenerator
.
addAndGet
(
PROBE_INCREMENT
);
int
probe
=
(
p
==
0
)
?
1
:
p
;
// skip 0
long
current
,
next
;
do
{
// same sequence as j.u.Random but different initial value
current
=
seedGenerator
.
get
();
next
=
current
*
181783497276652981L
;
}
while
(!
seedGenerator
.
compareAndSet
(
current
,
next
));
long
r
=
next
^
((
long
)
probe
<<
32
)
^
System
.
nanoTime
();
long
seed
=
mix64
(
seeder
.
getAndAdd
(
SEEDER_INCREMENT
));
Thread
t
=
Thread
.
currentThread
();
UNSAFE
.
putLong
(
t
,
SEED
,
r
);
UNSAFE
.
putLong
(
t
,
SEED
,
seed
);
UNSAFE
.
putInt
(
t
,
PROBE
,
probe
);
}
...
...
@@ -191,124 +220,264 @@ public class ThreadLocalRandom extends Random {
throw
new
UnsupportedOperationException
();
}
protected
int
next
(
int
bits
)
{
final
long
nextSeed
(
)
{
Thread
t
;
long
r
;
// read and update per-thread seed
UNSAFE
.
putLong
(
t
=
Thread
.
currentThread
(),
SEED
,
r
=
(
UNSAFE
.
getLong
(
t
,
SEED
)
*
multiplier
+
addend
)
&
mask
);
return
(
int
)
(
r
>>>
(
48
-
bits
));
UNSAFE
.
putLong
(
t
=
Thread
.
currentThread
(),
SEED
,
r
=
UNSAFE
.
getLong
(
t
,
SEED
)
+
GAMMA
);
return
r
;
}
// We must define this, but never use it.
protected
int
next
(
int
bits
)
{
return
(
int
)(
mix64
(
nextSeed
())
>>>
(
64
-
bits
));
}
// IllegalArgumentException messages
static
final
String
BadBound
=
"bound must be positive"
;
static
final
String
BadRange
=
"bound must be greater than origin"
;
static
final
String
BadSize
=
"size must be non-negative"
;
/**
* Returns a pseudorandom, uniformly distributed value between the
* given least value (inclusive) and bound (exclusive).
* The form of nextLong used by LongStream Spliterators. If
* origin is greater than bound, acts as unbounded form of
* nextLong, else as bounded form.
*
* @param least the least value returned
* @param bound the upper bound (exclusive)
* @throws IllegalArgumentException if least greater than or equal
* to bound
* @return the next value
*/
public
int
nextInt
(
int
least
,
int
bound
)
{
if
(
least
>=
bound
)
throw
new
IllegalArgumentException
();
return
nextInt
(
bound
-
least
)
+
least
;
}
/**
* Returns a pseudorandom, uniformly distributed value
* between 0 (inclusive) and the specified value (exclusive).
*
* @param n the bound on the random number to be returned. Must be
* positive.
* @return the next value
* @throws IllegalArgumentException if n is not positive
*/
public
long
nextLong
(
long
n
)
{
if
(
n
<=
0
)
throw
new
IllegalArgumentException
(
"n must be positive"
);
// Divide n by two until small enough for nextInt. On each
// iteration (at most 31 of them but usually much less),
// randomly choose both whether to include high bit in result
// (offset) and whether to continue with the lower vs upper
// half (which makes a difference only if odd).
long
offset
=
0
;
while
(
n
>=
Integer
.
MAX_VALUE
)
{
int
bits
=
next
(
2
);
long
half
=
n
>>>
1
;
long
nextn
=
((
bits
&
2
)
==
0
)
?
half
:
n
-
half
;
if
((
bits
&
1
)
==
0
)
offset
+=
n
-
nextn
;
n
=
nextn
;
}
return
offset
+
nextInt
((
int
)
n
);
}
@Override
public
IntStream
ints
()
{
return
IntStream
.
generate
(()
->
current
().
nextInt
());
* @param origin the least value, unless greater than bound
* @param bound the upper bound (exclusive), must not equal origin
* @return a pseudorandom value
*/
final
long
internalNextLong
(
long
origin
,
long
bound
)
{
long
r
=
mix64
(
nextSeed
());
if
(
origin
<
bound
)
{
long
n
=
bound
-
origin
,
m
=
n
-
1
;
if
((
n
&
m
)
==
0L
)
// power of two
r
=
(
r
&
m
)
+
origin
;
else
if
(
n
>
0L
)
{
// reject over-represented candidates
for
(
long
u
=
r
>>>
1
;
// ensure nonnegative
u
+
m
-
(
r
=
u
%
n
)
<
0L
;
// rejection check
u
=
mix64
(
nextSeed
())
>>>
1
)
// retry
;
r
+=
origin
;
}
else
{
// range not representable as long
while
(
r
<
origin
||
r
>=
bound
)
r
=
mix64
(
nextSeed
());
}
}
return
r
;
}
@Override
public
LongStream
longs
()
{
return
LongStream
.
generate
(()
->
current
().
nextLong
());
/**
* The form of nextInt used by IntStream Spliterators.
* Exactly the same as long version, except for types.
*
* @param origin the least value, unless greater than bound
* @param bound the upper bound (exclusive), must not equal origin
* @return a pseudorandom value
*/
final
int
internalNextInt
(
int
origin
,
int
bound
)
{
int
r
=
mix32
(
nextSeed
());
if
(
origin
<
bound
)
{
int
n
=
bound
-
origin
,
m
=
n
-
1
;
if
((
n
&
m
)
==
0
)
r
=
(
r
&
m
)
+
origin
;
else
if
(
n
>
0
)
{
for
(
int
u
=
r
>>>
1
;
u
+
m
-
(
r
=
u
%
n
)
<
0
;
u
=
mix32
(
nextSeed
())
>>>
1
)
;
r
+=
origin
;
}
else
{
while
(
r
<
origin
||
r
>=
bound
)
r
=
mix32
(
nextSeed
());
}
}
return
r
;
}
@Override
public
DoubleStream
doubles
()
{
return
DoubleStream
.
generate
(()
->
current
().
nextDouble
());
/**
* The form of nextDouble used by DoubleStream Spliterators.
*
* @param origin the least value, unless greater than bound
* @param bound the upper bound (exclusive), must not equal origin
* @return a pseudorandom value
*/
final
double
internalNextDouble
(
double
origin
,
double
bound
)
{
double
r
=
(
nextLong
()
>>>
11
)
*
DOUBLE_UNIT
;
if
(
origin
<
bound
)
{
r
=
r
*
(
bound
-
origin
)
+
origin
;
if
(
r
>=
bound
)
// correct for rounding
r
=
Double
.
longBitsToDouble
(
Double
.
doubleToLongBits
(
bound
)
-
1
);
}
return
r
;
}
/**
* Returns a pseudorandom {@code int} value.
*
* @return a pseudorandom {@code int} value
*/
public
int
nextInt
()
{
return
mix32
(
nextSeed
());
}
@Override
public
DoubleStream
gaussians
()
{
return
DoubleStream
.
generate
(()
->
current
().
nextGaussian
());
/**
* Returns a pseudorandom {@code int} value between zero (inclusive)
* and the specified bound (exclusive).
*
* @param bound the upper bound (exclusive). Must be positive.
* @return a pseudorandom {@code int} value between zero
* (inclusive) and the bound (exclusive)
* @throws IllegalArgumentException if {@code bound} is not positive
*/
public
int
nextInt
(
int
bound
)
{
if
(
bound
<=
0
)
throw
new
IllegalArgumentException
(
BadBound
);
int
r
=
mix32
(
nextSeed
());
int
m
=
bound
-
1
;
if
((
bound
&
m
)
==
0
)
// power of two
r
&=
m
;
else
{
// reject over-represented candidates
for
(
int
u
=
r
>>>
1
;
u
+
m
-
(
r
=
u
%
bound
)
<
0
;
u
=
mix32
(
nextSeed
())
>>>
1
)
;
}
return
r
;
}
/**
* Returns a pseudorandom {@code int} value between the specified
* origin (inclusive) and the specified bound (exclusive).
*
* @param origin the least value returned
* @param bound the upper bound (exclusive)
* @return a pseudorandom {@code int} value between the origin
* (inclusive) and the bound (exclusive)
* @throws IllegalArgumentException if {@code origin} is greater than
* or equal to {@code bound}
*/
public
int
nextInt
(
int
origin
,
int
bound
)
{
if
(
origin
>=
bound
)
throw
new
IllegalArgumentException
(
BadRange
);
return
internalNextInt
(
origin
,
bound
);
}
/**
* Returns a pseudorandom {@code long} value.
*
* @return a pseudorandom {@code long} value
*/
public
long
nextLong
()
{
return
mix64
(
nextSeed
());
}
/**
* Returns a pseudorandom {@code long} value between zero (inclusive)
* and the specified bound (exclusive).
*
* @param bound the upper bound (exclusive). Must be positive.
* @return a pseudorandom {@code long} value between zero
* (inclusive) and the bound (exclusive)
* @throws IllegalArgumentException if {@code bound} is not positive
*/
public
long
nextLong
(
long
bound
)
{
if
(
bound
<=
0
)
throw
new
IllegalArgumentException
(
BadBound
);
long
r
=
mix64
(
nextSeed
());
long
m
=
bound
-
1
;
if
((
bound
&
m
)
==
0L
)
// power of two
r
&=
m
;
else
{
// reject over-represented candidates
for
(
long
u
=
r
>>>
1
;
u
+
m
-
(
r
=
u
%
bound
)
<
0L
;
u
=
mix64
(
nextSeed
())
>>>
1
)
;
}
return
r
;
}
/**
* Returns a pseudorandom
, uniformly distributed value between the
*
given least value (inclusive) an
d bound (exclusive).
* Returns a pseudorandom
{@code long} value between the specified
*
origin (inclusive) and the specifie
d bound (exclusive).
*
* @param
least
the least value returned
* @param
origin
the least value returned
* @param bound the upper bound (exclusive)
* @return the next value
* @throws IllegalArgumentException if least greater than or equal
* to bound
* @return a pseudorandom {@code long} value between the origin
* (inclusive) and the bound (exclusive)
* @throws IllegalArgumentException if {@code origin} is greater than
* or equal to {@code bound}
*/
public
long
nextLong
(
long
origin
,
long
bound
)
{
if
(
origin
>=
bound
)
throw
new
IllegalArgumentException
(
BadRange
);
return
internalNextLong
(
origin
,
bound
);
}
/**
* Returns a pseudorandom {@code double} value between zero
* (inclusive) and one (exclusive).
*
* @return a pseudorandom {@code double} value between zero
* (inclusive) and one (exclusive)
*/
public
long
nextLong
(
long
least
,
long
bound
)
{
if
(
least
>=
bound
)
throw
new
IllegalArgumentException
();
return
nextLong
(
bound
-
least
)
+
least
;
public
double
nextDouble
()
{
return
(
mix64
(
nextSeed
())
>>>
11
)
*
DOUBLE_UNIT
;
}
/**
* Returns a pseudorandom
, uniformly distributed {@code double} value
*
between 0 (inclusive) and the specified value
(exclusive).
* Returns a pseudorandom
{@code double} value between 0.0
*
(inclusive) and the specified bound
(exclusive).
*
* @param
n the bound on the random number to be returned. Must be
*
positive.
*
@return the next value
* @throws IllegalArgumentException if
n
is not positive
* @param
bound the upper bound (exclusive). Must be positive.
*
@return a pseudorandom {@code double} value between zero
*
(inclusive) and the bound (exclusive)
* @throws IllegalArgumentException if
{@code bound}
is not positive
*/
public
double
nextDouble
(
double
n
)
{
if
(
n
<=
0
)
throw
new
IllegalArgumentException
(
"n must be positive"
);
return
nextDouble
()
*
n
;
public
double
nextDouble
(
double
bound
)
{
if
(!(
bound
>
0.0
))
throw
new
IllegalArgumentException
(
BadBound
);
double
result
=
(
mix64
(
nextSeed
())
>>>
11
)
*
DOUBLE_UNIT
*
bound
;
return
(
result
<
bound
)
?
result
:
// correct for rounding
Double
.
longBitsToDouble
(
Double
.
doubleToLongBits
(
bound
)
-
1
);
}
/**
* Returns a pseudorandom
, uniformly distributed value between the
*
given least value
(inclusive) and bound (exclusive).
* Returns a pseudorandom
{@code double} value between the specified
*
origin
(inclusive) and bound (exclusive).
*
* @param
least
the least value returned
* @param
origin
the least value returned
* @param bound the upper bound (exclusive)
* @return the next value
* @throws IllegalArgumentException if least greater than or equal
* to bound
* @return a pseudorandom {@code double} value between the origin
* (inclusive) and the bound (exclusive)
* @throws IllegalArgumentException if {@code origin} is greater than
* or equal to {@code bound}
*/
public
double
nextDouble
(
double
least
,
double
bound
)
{
if
(
least
>=
bound
)
throw
new
IllegalArgumentException
();
return
nextDouble
()
*
(
bound
-
least
)
+
least
;
public
double
nextDouble
(
double
origin
,
double
bound
)
{
if
(!(
origin
<
bound
))
throw
new
IllegalArgumentException
(
BadRange
);
return
internalNextDouble
(
origin
,
bound
);
}
/**
* Returns a pseudorandom {@code boolean} value.
*
* @return a pseudorandom {@code boolean} value
*/
public
boolean
nextBoolean
()
{
return
mix32
(
nextSeed
())
<
0
;
}
/**
* Returns a pseudorandom {@code float} value between zero
* (inclusive) and one (exclusive).
*
* @return a pseudorandom {@code float} value between zero
* (inclusive) and one (exclusive)
*/
public
float
nextFloat
()
{
return
(
mix32
(
nextSeed
())
>>>
8
)
*
FLOAT_UNIT
;
}
public
double
nextGaussian
()
{
...
...
@@ -329,6 +498,445 @@ public class ThreadLocalRandom extends Random {
return
v1
*
multiplier
;
}
// stream methods, coded in a way intended to better isolate for
// maintenance purposes the small differences across forms.
/**
* Returns a stream producing the given {@code streamSize} number of
* pseudorandom {@code int} values.
*
* @param streamSize the number of values to generate
* @return a stream of pseudorandom {@code int} values
* @throws IllegalArgumentException if {@code streamSize} is
* less than zero
* @since 1.8
*/
public
IntStream
ints
(
long
streamSize
)
{
if
(
streamSize
<
0L
)
throw
new
IllegalArgumentException
(
BadSize
);
return
StreamSupport
.
intStream
(
new
RandomIntsSpliterator
(
0L
,
streamSize
,
Integer
.
MAX_VALUE
,
0
),
false
);
}
/**
* Returns an effectively unlimited stream of pseudorandom {@code int}
* values.
*
* @implNote This method is implemented to be equivalent to {@code
* ints(Long.MAX_VALUE)}.
*
* @return a stream of pseudorandom {@code int} values
* @since 1.8
*/
public
IntStream
ints
()
{
return
StreamSupport
.
intStream
(
new
RandomIntsSpliterator
(
0L
,
Long
.
MAX_VALUE
,
Integer
.
MAX_VALUE
,
0
),
false
);
}
/**
* Returns a stream producing the given {@code streamSize} number
* of pseudorandom {@code int} values, each conforming to the given
* origin (inclusive) and bound (exclusive).
*
* @param streamSize the number of values to generate
* @param randomNumberOrigin the origin (inclusive) of each random value
* @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code int} values,
* each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException if {@code streamSize} is
* less than zero, or {@code randomNumberOrigin}
* is greater than or equal to {@code randomNumberBound}
* @since 1.8
*/
public
IntStream
ints
(
long
streamSize
,
int
randomNumberOrigin
,
int
randomNumberBound
)
{
if
(
streamSize
<
0L
)
throw
new
IllegalArgumentException
(
BadSize
);
if
(
randomNumberOrigin
>=
randomNumberBound
)
throw
new
IllegalArgumentException
(
BadRange
);
return
StreamSupport
.
intStream
(
new
RandomIntsSpliterator
(
0L
,
streamSize
,
randomNumberOrigin
,
randomNumberBound
),
false
);
}
/**
* Returns an effectively unlimited stream of pseudorandom {@code
* int} values, each conforming to the given origin (inclusive) and bound
* (exclusive).
*
* @implNote This method is implemented to be equivalent to {@code
* ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
*
* @param randomNumberOrigin the origin (inclusive) of each random value
* @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code int} values,
* each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException if {@code randomNumberOrigin}
* is greater than or equal to {@code randomNumberBound}
* @since 1.8
*/
public
IntStream
ints
(
int
randomNumberOrigin
,
int
randomNumberBound
)
{
if
(
randomNumberOrigin
>=
randomNumberBound
)
throw
new
IllegalArgumentException
(
BadRange
);
return
StreamSupport
.
intStream
(
new
RandomIntsSpliterator
(
0L
,
Long
.
MAX_VALUE
,
randomNumberOrigin
,
randomNumberBound
),
false
);
}
/**
* Returns a stream producing the given {@code streamSize} number of
* pseudorandom {@code long} values.
*
* @param streamSize the number of values to generate
* @return a stream of pseudorandom {@code long} values
* @throws IllegalArgumentException if {@code streamSize} is
* less than zero
* @since 1.8
*/
public
LongStream
longs
(
long
streamSize
)
{
if
(
streamSize
<
0L
)
throw
new
IllegalArgumentException
(
BadSize
);
return
StreamSupport
.
longStream
(
new
RandomLongsSpliterator
(
0L
,
streamSize
,
Long
.
MAX_VALUE
,
0L
),
false
);
}
/**
* Returns an effectively unlimited stream of pseudorandom {@code long}
* values.
*
* @implNote This method is implemented to be equivalent to {@code
* longs(Long.MAX_VALUE)}.
*
* @return a stream of pseudorandom {@code long} values
* @since 1.8
*/
public
LongStream
longs
()
{
return
StreamSupport
.
longStream
(
new
RandomLongsSpliterator
(
0L
,
Long
.
MAX_VALUE
,
Long
.
MAX_VALUE
,
0L
),
false
);
}
/**
* Returns a stream producing the given {@code streamSize} number of
* pseudorandom {@code long}, each conforming to the given origin
* (inclusive) and bound (exclusive).
*
* @param streamSize the number of values to generate
* @param randomNumberOrigin the origin (inclusive) of each random value
* @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code long} values,
* each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException if {@code streamSize} is
* less than zero, or {@code randomNumberOrigin}
* is greater than or equal to {@code randomNumberBound}
* @since 1.8
*/
public
LongStream
longs
(
long
streamSize
,
long
randomNumberOrigin
,
long
randomNumberBound
)
{
if
(
streamSize
<
0L
)
throw
new
IllegalArgumentException
(
BadSize
);
if
(
randomNumberOrigin
>=
randomNumberBound
)
throw
new
IllegalArgumentException
(
BadRange
);
return
StreamSupport
.
longStream
(
new
RandomLongsSpliterator
(
0L
,
streamSize
,
randomNumberOrigin
,
randomNumberBound
),
false
);
}
/**
* Returns an effectively unlimited stream of pseudorandom {@code
* long} values, each conforming to the given origin (inclusive) and bound
* (exclusive).
*
* @implNote This method is implemented to be equivalent to {@code
* longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
*
* @param randomNumberOrigin the origin (inclusive) of each random value
* @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code long} values,
* each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException if {@code randomNumberOrigin}
* is greater than or equal to {@code randomNumberBound}
* @since 1.8
*/
public
LongStream
longs
(
long
randomNumberOrigin
,
long
randomNumberBound
)
{
if
(
randomNumberOrigin
>=
randomNumberBound
)
throw
new
IllegalArgumentException
(
BadRange
);
return
StreamSupport
.
longStream
(
new
RandomLongsSpliterator
(
0L
,
Long
.
MAX_VALUE
,
randomNumberOrigin
,
randomNumberBound
),
false
);
}
/**
* Returns a stream producing the given {@code streamSize} number of
* pseudorandom {@code double} values, each between zero
* (inclusive) and one (exclusive).
*
* @param streamSize the number of values to generate
* @return a stream of {@code double} values
* @throws IllegalArgumentException if {@code streamSize} is
* less than zero
* @since 1.8
*/
public
DoubleStream
doubles
(
long
streamSize
)
{
if
(
streamSize
<
0L
)
throw
new
IllegalArgumentException
(
BadSize
);
return
StreamSupport
.
doubleStream
(
new
RandomDoublesSpliterator
(
0L
,
streamSize
,
Double
.
MAX_VALUE
,
0.0
),
false
);
}
/**
* Returns an effectively unlimited stream of pseudorandom {@code
* double} values, each between zero (inclusive) and one
* (exclusive).
*
* @implNote This method is implemented to be equivalent to {@code
* doubles(Long.MAX_VALUE)}.
*
* @return a stream of pseudorandom {@code double} values
* @since 1.8
*/
public
DoubleStream
doubles
()
{
return
StreamSupport
.
doubleStream
(
new
RandomDoublesSpliterator
(
0L
,
Long
.
MAX_VALUE
,
Double
.
MAX_VALUE
,
0.0
),
false
);
}
/**
* Returns a stream producing the given {@code streamSize} number of
* pseudorandom {@code double} values, each conforming to the given origin
* (inclusive) and bound (exclusive).
*
* @param streamSize the number of values to generate
* @param randomNumberOrigin the origin (inclusive) of each random value
* @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code double} values,
* each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException if {@code streamSize} is
* less than zero
* @throws IllegalArgumentException if {@code randomNumberOrigin}
* is greater than or equal to {@code randomNumberBound}
* @since 1.8
*/
public
DoubleStream
doubles
(
long
streamSize
,
double
randomNumberOrigin
,
double
randomNumberBound
)
{
if
(
streamSize
<
0L
)
throw
new
IllegalArgumentException
(
BadSize
);
if
(!(
randomNumberOrigin
<
randomNumberBound
))
throw
new
IllegalArgumentException
(
BadRange
);
return
StreamSupport
.
doubleStream
(
new
RandomDoublesSpliterator
(
0L
,
streamSize
,
randomNumberOrigin
,
randomNumberBound
),
false
);
}
/**
* Returns an effectively unlimited stream of pseudorandom {@code
* double} values, each conforming to the given origin (inclusive) and bound
* (exclusive).
*
* @implNote This method is implemented to be equivalent to {@code
* doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
*
* @param randomNumberOrigin the origin (inclusive) of each random value
* @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code double} values,
* each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException if {@code randomNumberOrigin}
* is greater than or equal to {@code randomNumberBound}
* @since 1.8
*/
public
DoubleStream
doubles
(
double
randomNumberOrigin
,
double
randomNumberBound
)
{
if
(!(
randomNumberOrigin
<
randomNumberBound
))
throw
new
IllegalArgumentException
(
BadRange
);
return
StreamSupport
.
doubleStream
(
new
RandomDoublesSpliterator
(
0L
,
Long
.
MAX_VALUE
,
randomNumberOrigin
,
randomNumberBound
),
false
);
}
/**
* Spliterator for int streams. We multiplex the four int
* versions into one class by treating a bound less than origin as
* unbounded, and also by treating "infinite" as equivalent to
* Long.MAX_VALUE. For splits, it uses the standard divide-by-two
* approach. The long and double versions of this class are
* identical except for types.
*/
static
final
class
RandomIntsSpliterator
implements
Spliterator
.
OfInt
{
long
index
;
final
long
fence
;
final
int
origin
;
final
int
bound
;
RandomIntsSpliterator
(
long
index
,
long
fence
,
int
origin
,
int
bound
)
{
this
.
index
=
index
;
this
.
fence
=
fence
;
this
.
origin
=
origin
;
this
.
bound
=
bound
;
}
public
RandomIntsSpliterator
trySplit
()
{
long
i
=
index
,
m
=
(
i
+
fence
)
>>>
1
;
return
(
m
<=
i
)
?
null
:
new
RandomIntsSpliterator
(
i
,
index
=
m
,
origin
,
bound
);
}
public
long
estimateSize
()
{
return
fence
-
index
;
}
public
int
characteristics
()
{
return
(
Spliterator
.
SIZED
|
Spliterator
.
SUBSIZED
|
Spliterator
.
NONNULL
|
Spliterator
.
IMMUTABLE
);
}
public
boolean
tryAdvance
(
IntConsumer
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
consumer
.
accept
(
ThreadLocalRandom
.
current
().
internalNextInt
(
origin
,
bound
));
index
=
i
+
1
;
return
true
;
}
return
false
;
}
public
void
forEachRemaining
(
IntConsumer
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
index
=
f
;
int
o
=
origin
,
b
=
bound
;
ThreadLocalRandom
rng
=
ThreadLocalRandom
.
current
();
do
{
consumer
.
accept
(
rng
.
internalNextInt
(
o
,
b
));
}
while
(++
i
<
f
);
}
}
}
/**
* Spliterator for long streams.
*/
static
final
class
RandomLongsSpliterator
implements
Spliterator
.
OfLong
{
long
index
;
final
long
fence
;
final
long
origin
;
final
long
bound
;
RandomLongsSpliterator
(
long
index
,
long
fence
,
long
origin
,
long
bound
)
{
this
.
index
=
index
;
this
.
fence
=
fence
;
this
.
origin
=
origin
;
this
.
bound
=
bound
;
}
public
RandomLongsSpliterator
trySplit
()
{
long
i
=
index
,
m
=
(
i
+
fence
)
>>>
1
;
return
(
m
<=
i
)
?
null
:
new
RandomLongsSpliterator
(
i
,
index
=
m
,
origin
,
bound
);
}
public
long
estimateSize
()
{
return
fence
-
index
;
}
public
int
characteristics
()
{
return
(
Spliterator
.
SIZED
|
Spliterator
.
SUBSIZED
|
Spliterator
.
NONNULL
|
Spliterator
.
IMMUTABLE
);
}
public
boolean
tryAdvance
(
LongConsumer
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
consumer
.
accept
(
ThreadLocalRandom
.
current
().
internalNextLong
(
origin
,
bound
));
index
=
i
+
1
;
return
true
;
}
return
false
;
}
public
void
forEachRemaining
(
LongConsumer
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
index
=
f
;
long
o
=
origin
,
b
=
bound
;
ThreadLocalRandom
rng
=
ThreadLocalRandom
.
current
();
do
{
consumer
.
accept
(
rng
.
internalNextLong
(
o
,
b
));
}
while
(++
i
<
f
);
}
}
}
/**
* Spliterator for double streams.
*/
static
final
class
RandomDoublesSpliterator
implements
Spliterator
.
OfDouble
{
long
index
;
final
long
fence
;
final
double
origin
;
final
double
bound
;
RandomDoublesSpliterator
(
long
index
,
long
fence
,
double
origin
,
double
bound
)
{
this
.
index
=
index
;
this
.
fence
=
fence
;
this
.
origin
=
origin
;
this
.
bound
=
bound
;
}
public
RandomDoublesSpliterator
trySplit
()
{
long
i
=
index
,
m
=
(
i
+
fence
)
>>>
1
;
return
(
m
<=
i
)
?
null
:
new
RandomDoublesSpliterator
(
i
,
index
=
m
,
origin
,
bound
);
}
public
long
estimateSize
()
{
return
fence
-
index
;
}
public
int
characteristics
()
{
return
(
Spliterator
.
SIZED
|
Spliterator
.
SUBSIZED
|
Spliterator
.
NONNULL
|
Spliterator
.
IMMUTABLE
);
}
public
boolean
tryAdvance
(
DoubleConsumer
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
consumer
.
accept
(
ThreadLocalRandom
.
current
().
internalNextDouble
(
origin
,
bound
));
index
=
i
+
1
;
return
true
;
}
return
false
;
}
public
void
forEachRemaining
(
DoubleConsumer
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
index
=
f
;
double
o
=
origin
,
b
=
bound
;
ThreadLocalRandom
rng
=
ThreadLocalRandom
.
current
();
do
{
consumer
.
accept
(
rng
.
internalNextDouble
(
o
,
b
));
}
while
(++
i
<
f
);
}
}
}
// Within-package utilities
/*
...
...
@@ -401,23 +1009,26 @@ public class ThreadLocalRandom extends Random {
*/
private
static
final
ObjectStreamField
[]
serialPersistentFields
=
{
new
ObjectStreamField
(
"rnd"
,
long
.
class
),
new
ObjectStreamField
(
"initialized"
,
boolean
.
class
)
new
ObjectStreamField
(
"initialized"
,
boolean
.
class
)
,
};
/**
* Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it).
* @param s the stream
* @throws java.io.IOException if an I/O error occurs
*/
private
void
writeObject
(
java
.
io
.
ObjectOutputStream
out
)
private
void
writeObject
(
java
.
io
.
ObjectOutputStream
s
)
throws
java
.
io
.
IOException
{
java
.
io
.
ObjectOutputStream
.
PutField
fields
=
out
.
putFields
();
java
.
io
.
ObjectOutputStream
.
PutField
fields
=
s
.
putFields
();
fields
.
put
(
"rnd"
,
UNSAFE
.
getLong
(
Thread
.
currentThread
(),
SEED
));
fields
.
put
(
"initialized"
,
true
);
out
.
writeFields
();
s
.
writeFields
();
}
/**
* Returns the {@link #current() current} thread's {@code ThreadLocalRandom}.
* @return the {@link #current() current} thread's {@code ThreadLocalRandom}
*/
private
Object
readResolve
()
{
return
current
();
...
...
src/share/classes/java/util/concurrent/locks/StampedLock.java
浏览文件 @
f9ad02d9
...
...
@@ -226,7 +226,11 @@ public class StampedLock implements java.io.Serializable {
* incoming reader arrives while read lock is held but there is a
* queued writer, this incoming reader is queued. (This rule is
* responsible for some of the complexity of method acquireRead,
* but without it, the lock becomes highly unfair.)
* but without it, the lock becomes highly unfair.) Method release
* does not (and sometimes cannot) itself wake up cowaiters. This
* is done by the primary thread, but helped by any other threads
* with nothing better to do in methods acquireRead and
* acquireWrite.
*
* These rules apply to threads actually queued. All tryLock forms
* opportunistically try to acquire locks regardless of preference
...
...
@@ -267,11 +271,14 @@ public class StampedLock implements java.io.Serializable {
/** Number of processors, for spin control */
private
static
final
int
NCPU
=
Runtime
.
getRuntime
().
availableProcessors
();
/** Maximum number of retries before
block
ing on acquisition */
/** Maximum number of retries before
enqueu
ing on acquisition */
private
static
final
int
SPINS
=
(
NCPU
>
1
)
?
1
<<
6
:
0
;
/** Maximum number of retries before blocking at head on acquisition */
private
static
final
int
HEAD_SPINS
=
(
NCPU
>
1
)
?
1
<<
10
:
0
;
/** Maximum number of retries before re-blocking */
private
static
final
int
MAX_HEAD_SPINS
=
(
NCPU
>
1
)
?
1
<<
1
2
:
0
;
private
static
final
int
MAX_HEAD_SPINS
=
(
NCPU
>
1
)
?
1
<<
1
6
:
0
;
/** The period for yielding when waiting for overflow spinlock */
private
static
final
int
OVERFLOW_YIELD_RATE
=
7
;
// must be power 2 - 1
...
...
@@ -415,8 +422,8 @@ public class StampedLock implements java.io.Serializable {
* @return a stamp that can be used to unlock or convert mode
*/
public
long
readLock
()
{
long
s
,
next
;
// bypass acquireRead on fully unlocked case only
return
((
((
s
=
state
)
&
ABITS
)
==
0
L
&&
long
s
=
state
,
next
;
// bypass acquireRead on common uncontended case
return
((
whead
==
wtail
&&
(
s
&
ABITS
)
<
RFUL
L
&&
U
.
compareAndSwapLong
(
this
,
STATE
,
s
,
next
=
s
+
RUNIT
))
?
next
:
acquireRead
(
false
,
0L
));
}
...
...
@@ -1012,18 +1019,9 @@ public class StampedLock implements java.io.Serializable {
if
(
t
.
status
<=
0
)
q
=
t
;
}
if
(
q
!=
null
)
{
for
(
WNode
r
=
q
;;)
{
// release co-waiters too
if
((
w
=
r
.
thread
)
!=
null
)
{
r
.
thread
=
null
;
if
(
q
!=
null
&&
(
w
=
q
.
thread
)
!=
null
)
U
.
unpark
(
w
);
}
if
((
r
=
q
.
cowait
)
==
null
)
break
;
U
.
compareAndSwapObject
(
q
,
WCOWAIT
,
r
,
r
.
cowait
);
}
}
}
}
/**
...
...
@@ -1038,22 +1036,22 @@ public class StampedLock implements java.io.Serializable {
private
long
acquireWrite
(
boolean
interruptible
,
long
deadline
)
{
WNode
node
=
null
,
p
;
for
(
int
spins
=
-
1
;;)
{
// spin while enqueuing
long
s
,
ns
;
if
(((
s
=
state
)
&
ABITS
)
==
0L
)
{
long
m
,
s
,
ns
;
if
((
m
=
(
s
=
state
)
&
ABITS
)
==
0L
)
{
if
(
U
.
compareAndSwapLong
(
this
,
STATE
,
s
,
ns
=
s
+
WBIT
))
return
ns
;
}
else
if
(
spins
<
0
)
spins
=
(
m
==
WBIT
&&
wtail
==
whead
)
?
SPINS
:
0
;
else
if
(
spins
>
0
)
{
if
(
LockSupport
.
nextSecondarySeed
()
>=
0
)
--
spins
;
}
else
if
((
p
=
wtail
)
==
null
)
{
// initialize queue
WNode
h
=
new
WNode
(
WMODE
,
null
);
if
(
U
.
compareAndSwapObject
(
this
,
WHEAD
,
null
,
h
))
wtail
=
h
;
WNode
h
d
=
new
WNode
(
WMODE
,
null
);
if
(
U
.
compareAndSwapObject
(
this
,
WHEAD
,
null
,
h
d
))
wtail
=
h
d
;
}
else
if
(
spins
<
0
)
spins
=
(
p
==
whead
)
?
SPINS
:
0
;
else
if
(
node
==
null
)
node
=
new
WNode
(
WMODE
,
p
);
else
if
(
node
.
prev
!=
p
)
...
...
@@ -1064,14 +1062,18 @@ public class StampedLock implements java.io.Serializable {
}
}
for
(
int
spins
=
SPINS
;;)
{
WNode
np
,
pp
;
int
ps
;
long
s
,
ns
;
Thread
w
;
while
((
np
=
node
.
prev
)
!=
p
&&
np
!=
null
)
(
p
=
np
).
next
=
node
;
// stale
if
(
whead
==
p
)
{
for
(
int
spins
=
-
1
;;)
{
WNode
h
,
np
,
pp
;
int
ps
;
if
((
h
=
whead
)
==
p
)
{
if
(
spins
<
0
)
spins
=
HEAD_SPINS
;
else
if
(
spins
<
MAX_HEAD_SPINS
)
spins
<<=
1
;
for
(
int
k
=
spins
;;)
{
// spin at head
long
s
,
ns
;
if
(((
s
=
state
)
&
ABITS
)
==
0L
)
{
if
(
U
.
compareAndSwapLong
(
this
,
STATE
,
s
,
ns
=
s
+
WBIT
))
{
if
(
U
.
compareAndSwapLong
(
this
,
STATE
,
s
,
ns
=
s
+
WBIT
))
{
whead
=
node
;
node
.
prev
=
null
;
return
ns
;
...
...
@@ -1081,10 +1083,21 @@ public class StampedLock implements java.io.Serializable {
--
k
<=
0
)
break
;
}
if
(
spins
<
MAX_HEAD_SPINS
)
spins
<<=
1
;
}
if
((
ps
=
p
.
status
)
==
0
)
else
if
(
h
!=
null
)
{
// help release stale waiters
WNode
c
;
Thread
w
;
while
((
c
=
h
.
cowait
)
!=
null
)
{
if
(
U
.
compareAndSwapObject
(
h
,
WCOWAIT
,
c
,
c
.
cowait
)
&&
(
w
=
c
.
thread
)
!=
null
)
U
.
unpark
(
w
);
}
}
if
(
whead
==
h
)
{
if
((
np
=
node
.
prev
)
!=
p
)
{
if
(
np
!=
null
)
(
p
=
np
).
next
=
node
;
// stale
}
else
if
((
ps
=
p
.
status
)
==
0
)
U
.
compareAndSwapInt
(
p
,
WSTATUS
,
0
,
WAITING
);
else
if
(
ps
==
CANCELLED
)
{
if
((
pp
=
p
.
prev
)
!=
null
)
{
...
...
@@ -1099,11 +1112,11 @@ public class StampedLock implements java.io.Serializable {
else
if
((
time
=
deadline
-
System
.
nanoTime
())
<=
0L
)
return
cancelWaiter
(
node
,
node
,
false
);
Thread
wt
=
Thread
.
currentThread
();
U
.
putObject
(
wt
,
PARKBLOCKER
,
this
);
// emulate LockSupport.park
U
.
putObject
(
wt
,
PARKBLOCKER
,
this
);
node
.
thread
=
wt
;
if
(
node
.
prev
==
p
&&
p
.
status
==
WAITING
&&
// recheck
(
p
!=
whead
||
(
state
&
ABITS
)
!=
0L
)
)
U
.
park
(
false
,
time
);
if
(
p
.
status
<
0
&&
(
p
!=
h
||
(
state
&
ABITS
)
!=
0L
)
&&
whead
==
h
&&
node
.
prev
==
p
)
U
.
park
(
false
,
time
);
// emulate LockSupport.park
node
.
thread
=
null
;
U
.
putObject
(
wt
,
PARKBLOCKER
,
null
);
if
(
interruptible
&&
Thread
.
interrupted
())
...
...
@@ -1111,6 +1124,7 @@ public class StampedLock implements java.io.Serializable {
}
}
}
}
/**
* See above for explanation.
...
...
@@ -1122,115 +1136,134 @@ public class StampedLock implements java.io.Serializable {
* @return next state, or INTERRUPTED
*/
private
long
acquireRead
(
boolean
interruptible
,
long
deadline
)
{
WNode
node
=
null
,
group
=
null
,
p
;
WNode
node
=
null
,
p
;
for
(
int
spins
=
-
1
;;)
{
for
(;;)
{
long
s
,
m
,
ns
;
WNode
h
,
q
;
Thread
w
;
// anti-barging guard
if
(
group
==
null
&&
(
h
=
whead
)
!=
null
&&
(
q
=
h
.
next
)
!=
null
&&
q
.
mode
!=
RMODE
)
break
;
WNode
h
;
if
((
h
=
whead
)
==
(
p
=
wtail
))
{
for
(
long
m
,
s
,
ns
;;)
{
if
((
m
=
(
s
=
state
)
&
ABITS
)
<
RFULL
?
U
.
compareAndSwapLong
(
this
,
STATE
,
s
,
ns
=
s
+
RUNIT
)
:
(
m
<
WBIT
&&
(
ns
=
tryIncReaderOverflow
(
s
))
!=
0L
))
{
if
(
group
!=
null
)
{
// help release others
for
(
WNode
r
=
group
;;
)
{
if
((
w
=
r
.
thread
)
!=
null
)
{
r
.
thread
=
null
;
U
.
unpark
(
w
)
;
(
m
<
WBIT
&&
(
ns
=
tryIncReaderOverflow
(
s
))
!=
0L
))
return
ns
;
else
if
(
m
>=
WBIT
)
{
if
(
spins
>
0
)
{
if
(
LockSupport
.
nextSecondarySeed
()
>=
0
)
--
spins
;
}
if
((
r
=
group
.
cowait
)
==
null
)
else
{
if
(
spins
==
0
)
{
WNode
nh
=
whead
,
np
=
wtail
;
if
((
nh
==
h
&&
np
==
p
)
||
(
h
=
nh
)
!=
(
p
=
np
))
break
;
U
.
compareAndSwapObject
(
group
,
WCOWAIT
,
r
,
r
.
cowait
);
}
spins
=
SPINS
;
}
return
ns
;
}
if
(
m
>=
WBIT
)
break
;
}
if
(
spins
>
0
)
{
if
(
LockSupport
.
nextSecondarySeed
()
>=
0
)
--
spins
;
}
else
if
((
p
=
wtail
)
==
null
)
{
WNode
h
=
new
WNode
(
WMODE
,
null
);
if
(
U
.
compareAndSwapObject
(
this
,
WHEAD
,
null
,
h
))
wtail
=
h
;
if
(
p
==
null
)
{
// initialize queue
WNode
h
d
=
new
WNode
(
WMODE
,
null
);
if
(
U
.
compareAndSwapObject
(
this
,
WHEAD
,
null
,
h
d
))
wtail
=
h
d
;
}
else
if
(
spins
<
0
)
spins
=
(
p
==
whead
)
?
SPINS
:
0
;
else
if
(
node
==
null
)
node
=
new
WNode
(
WMODE
,
p
);
else
if
(
node
.
prev
!=
p
)
node
=
new
WNode
(
RMODE
,
p
);
else
if
(
h
==
p
||
p
.
mode
!=
RMODE
)
{
if
(
node
.
prev
!=
p
)
node
.
prev
=
p
;
else
if
(
p
.
mode
==
RMODE
&&
p
!=
whead
)
{
WNode
pp
=
p
.
prev
;
// become co-waiter with group p
if
(
pp
!=
null
&&
p
==
wtail
&&
U
.
compareAndSwapObject
(
p
,
WCOWAIT
,
node
.
cowait
=
p
.
cowait
,
node
))
{
node
.
thread
=
Thread
.
currentThread
();
for
(
long
time
;;)
{
else
if
(
U
.
compareAndSwapObject
(
this
,
WTAIL
,
p
,
node
))
{
p
.
next
=
node
;
break
;
}
}
else
if
(!
U
.
compareAndSwapObject
(
p
,
WCOWAIT
,
node
.
cowait
=
p
.
cowait
,
node
))
node
.
cowait
=
null
;
else
{
for
(;;)
{
WNode
pp
,
c
;
Thread
w
;
if
((
h
=
whead
)
!=
null
&&
(
c
=
h
.
cowait
)
!=
null
&&
U
.
compareAndSwapObject
(
h
,
WCOWAIT
,
c
,
c
.
cowait
)
&&
(
w
=
c
.
thread
)
!=
null
)
// help release
U
.
unpark
(
w
);
if
(
h
==
(
pp
=
p
.
prev
)
||
h
==
p
||
pp
==
null
)
{
long
m
,
s
,
ns
;
do
{
if
((
m
=
(
s
=
state
)
&
ABITS
)
<
RFULL
?
U
.
compareAndSwapLong
(
this
,
STATE
,
s
,
ns
=
s
+
RUNIT
)
:
(
m
<
WBIT
&&
(
ns
=
tryIncReaderOverflow
(
s
))
!=
0L
))
return
ns
;
}
while
(
m
<
WBIT
);
}
if
(
whead
==
h
&&
p
.
prev
==
pp
)
{
long
time
;
if
(
pp
==
null
||
h
==
p
||
p
.
status
>
0
)
{
node
=
null
;
// throw away
break
;
}
if
(
deadline
==
0L
)
time
=
0L
;
else
if
((
time
=
deadline
-
System
.
nanoTime
())
<=
0L
)
return
cancelWaiter
(
node
,
p
,
false
);
if
(
node
.
thread
==
null
)
break
;
if
(
p
.
prev
!=
pp
||
p
.
status
==
CANCELLED
||
p
==
whead
||
p
.
prev
!=
pp
)
{
node
.
thread
=
null
;
break
;
}
Thread
wt
=
Thread
.
currentThread
();
U
.
putObject
(
wt
,
PARKBLOCKER
,
this
);
if
(
node
.
thread
==
null
)
// must recheck
break
;
node
.
thread
=
wt
;
if
((
h
!=
pp
||
(
state
&
ABITS
)
==
WBIT
)
&&
whead
==
h
&&
p
.
prev
==
pp
)
U
.
park
(
false
,
time
);
node
.
thread
=
null
;
U
.
putObject
(
wt
,
PARKBLOCKER
,
null
);
if
(
interruptible
&&
Thread
.
interrupted
())
return
cancelWaiter
(
node
,
p
,
true
);
}
group
=
p
;
}
node
=
null
;
// throw away
}
else
if
(
U
.
compareAndSwapObject
(
this
,
WTAIL
,
p
,
node
))
{
p
.
next
=
node
;
break
;
}
}
for
(
int
spins
=
SPINS
;;)
{
WNode
np
,
pp
,
r
;
int
ps
;
long
m
,
s
,
ns
;
Thread
w
;
while
((
np
=
node
.
prev
)
!=
p
&&
np
!=
null
)
(
p
=
np
).
next
=
node
;
if
(
whead
==
p
)
{
for
(
int
k
=
spins
;;)
{
if
((
m
=
(
s
=
state
)
&
ABITS
)
!=
WBIT
)
{
if
(
m
<
RFULL
?
U
.
compareAndSwapLong
(
this
,
STATE
,
s
,
ns
=
s
+
RUNIT
):
(
ns
=
tryIncReaderOverflow
(
s
))
!=
0L
)
{
for
(
int
spins
=
-
1
;;)
{
WNode
h
,
np
,
pp
;
int
ps
;
if
((
h
=
whead
)
==
p
)
{
if
(
spins
<
0
)
spins
=
HEAD_SPINS
;
else
if
(
spins
<
MAX_HEAD_SPINS
)
spins
<<=
1
;
for
(
int
k
=
spins
;;)
{
// spin at head
long
m
,
s
,
ns
;
if
((
m
=
(
s
=
state
)
&
ABITS
)
<
RFULL
?
U
.
compareAndSwapLong
(
this
,
STATE
,
s
,
ns
=
s
+
RUNIT
)
:
(
m
<
WBIT
&&
(
ns
=
tryIncReaderOverflow
(
s
))
!=
0L
))
{
WNode
c
;
Thread
w
;
whead
=
node
;
node
.
prev
=
null
;
while
((
r
=
node
.
cowait
)
!=
null
)
{
while
((
c
=
node
.
cowait
)
!=
null
)
{
if
(
U
.
compareAndSwapObject
(
node
,
WCOWAIT
,
r
,
r
.
cowait
)
&&
(
w
=
r
.
thread
)
!=
null
)
{
r
.
thread
=
null
;
U
.
unpark
(
w
);
// release co-waiter
}
c
,
c
.
cowait
)
&&
(
w
=
c
.
thread
)
!=
null
)
U
.
unpark
(
w
);
}
return
ns
;
}
}
else
if
(
LockSupport
.
nextSecondarySeed
()
>=
0
&&
--
k
<=
0
)
else
if
(
m
>=
WBIT
&&
LockSupport
.
nextSecondarySeed
()
>=
0
&&
--
k
<=
0
)
break
;
}
if
(
spins
<
MAX_HEAD_SPINS
)
spins
<<=
1
;
}
if
((
ps
=
p
.
status
)
==
0
)
else
if
(
h
!=
null
)
{
WNode
c
;
Thread
w
;
while
((
c
=
h
.
cowait
)
!=
null
)
{
if
(
U
.
compareAndSwapObject
(
h
,
WCOWAIT
,
c
,
c
.
cowait
)
&&
(
w
=
c
.
thread
)
!=
null
)
U
.
unpark
(
w
);
}
}
if
(
whead
==
h
)
{
if
((
np
=
node
.
prev
)
!=
p
)
{
if
(
np
!=
null
)
(
p
=
np
).
next
=
node
;
// stale
}
else
if
((
ps
=
p
.
status
)
==
0
)
U
.
compareAndSwapInt
(
p
,
WSTATUS
,
0
,
WAITING
);
else
if
(
ps
==
CANCELLED
)
{
if
((
pp
=
p
.
prev
)
!=
null
)
{
...
...
@@ -1247,8 +1280,9 @@ public class StampedLock implements java.io.Serializable {
Thread
wt
=
Thread
.
currentThread
();
U
.
putObject
(
wt
,
PARKBLOCKER
,
this
);
node
.
thread
=
wt
;
if
(
node
.
prev
==
p
&&
p
.
status
==
WAITING
&&
(
p
!=
whead
||
(
state
&
ABITS
)
!=
WBIT
))
if
(
p
.
status
<
0
&&
(
p
!=
h
||
(
state
&
ABITS
)
==
WBIT
)
&&
whead
==
h
&&
node
.
prev
==
p
)
U
.
park
(
false
,
time
);
node
.
thread
=
null
;
U
.
putObject
(
wt
,
PARKBLOCKER
,
null
);
...
...
@@ -1257,6 +1291,7 @@ public class StampedLock implements java.io.Serializable {
}
}
}
}
/**
* If node non-null, forces cancel status and unsplices it from
...
...
@@ -1278,22 +1313,19 @@ public class StampedLock implements java.io.Serializable {
if
(
node
!=
null
&&
group
!=
null
)
{
Thread
w
;
node
.
status
=
CANCELLED
;
node
.
thread
=
null
;
// unsplice cancelled nodes from group
for
(
WNode
p
=
group
,
q
;
(
q
=
p
.
cowait
)
!=
null
;)
{
if
(
q
.
status
==
CANCELLED
)
U
.
compareAndSwapObject
(
p
,
WNEXT
,
q
,
q
.
next
);
if
(
q
.
status
==
CANCELLED
)
{
U
.
compareAndSwapObject
(
p
,
WCOWAIT
,
q
,
q
.
cowait
);
p
=
group
;
// restart
}
else
p
=
q
;
}
if
(
group
==
node
)
{
WNode
r
;
// detach and wake up uncancelled co-waiters
while
((
r
=
node
.
cowait
)
!=
null
)
{
if
(
U
.
compareAndSwapObject
(
node
,
WCOWAIT
,
r
,
r
.
cowait
)
&&
(
w
=
r
.
thread
)
!=
null
)
{
r
.
thread
=
null
;
U
.
unpark
(
w
);
}
for
(
WNode
r
=
group
.
cowait
;
r
!=
null
;
r
=
r
.
cowait
)
{
if
((
w
=
r
.
thread
)
!=
null
)
U
.
unpark
(
w
);
// wake up uncancelled co-waiters
}
for
(
WNode
pred
=
node
.
prev
;
pred
!=
null
;
)
{
// unsplice
WNode
succ
,
pp
;
// find valid successor
...
...
src/share/classes/java/util/jar/JarVerifier.java
浏览文件 @
f9ad02d9
...
...
@@ -32,6 +32,7 @@ import java.security.*;
import
java.security.cert.CertificateException
;
import
java.util.zip.ZipEntry
;
import
sun.misc.JarIndex
;
import
sun.security.util.ManifestDigester
;
import
sun.security.util.ManifestEntryVerifier
;
import
sun.security.util.SignatureFileVerifier
;
...
...
@@ -139,7 +140,8 @@ class JarVerifier {
return
;
}
if
(
uname
.
equals
(
JarFile
.
MANIFEST_NAME
))
{
if
(
uname
.
equals
(
JarFile
.
MANIFEST_NAME
)
||
uname
.
equals
(
JarIndex
.
INDEX_NAME
))
{
return
;
}
...
...
src/share/classes/java/util/logging/Logger.java
浏览文件 @
f9ad02d9
...
...
@@ -457,13 +457,15 @@ public class Logger {
* of the subsystem, such as java.net
* or javax.swing
* @param resourceBundleName name of ResourceBundle to be used for localizing
* messages for this logger. May be
<CODE>null</CODE> if none of
* the messages require localization.
* messages for this logger. May be
{@code null}
*
if none of
the messages require localization.
* @return a suitable Logger
* @throws MissingResourceException if the resourceBundleName is non-null and
* no corresponding resource can be found.
* @throws IllegalArgumentException if the Logger already exists and uses
* a different resource bundle name.
* a different resource bundle name; or if
* {@code resourceBundleName} is {@code null} but the named
* logger has a resource bundle set.
* @throws NullPointerException if the name is null.
*/
...
...
@@ -1731,10 +1733,6 @@ public class Logger {
// Synchronized to prevent races in setting the fields.
private
synchronized
void
setupResourceInfo
(
String
name
,
Class
<?>
callersClass
)
{
if
(
name
==
null
)
{
return
;
}
if
(
resourceBundleName
!=
null
)
{
// this Logger already has a ResourceBundle
...
...
@@ -1748,6 +1746,10 @@ public class Logger {
resourceBundleName
+
" != "
+
name
);
}
if
(
name
==
null
)
{
return
;
}
setCallersClassLoaderRef
(
callersClass
);
if
(
findResourceBundle
(
name
,
true
)
==
null
)
{
// We've failed to find an expected ResourceBundle.
...
...
src/share/classes/java/util/regex/Pattern.java
浏览文件 @
f9ad02d9
...
...
@@ -219,7 +219,7 @@ import java.util.stream.StreamSupport;
*
* <tr><th> </th></tr>
* <tr align="left"><th colspan="2" id="unicode">Classes for Unicode scripts, blocks, categories and binary properties</th></tr>
*
*
<tr><td valign="top" headers="construct unicode">{@code \p{IsLatin}}</td>
* <tr><td valign="top" headers="construct unicode">{@code \p{IsLatin}}</td>
* <td headers="matches">A Latin script character (<a href="#usc">script</a>)</td></tr>
* <tr><td valign="top" headers="construct unicode">{@code \p{InGreek}}</td>
* <td headers="matches">A character in the Greek block (<a href="#ubc">block</a>)</td></tr>
...
...
@@ -4456,16 +4456,16 @@ loop: for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
groups
[
groupIndex
+
1
]
=
i
;
groups
[
groupIndex
]
=
i
-
k
;
}
i
=
i
-
k
;
return
true
;
}
// backing off
i
=
i
-
k
;
if
(
capture
)
{
groups
[
groupIndex
+
1
]
=
i
;
groups
[
groupIndex
]
=
i
-
k
;
}
i
=
i
-
k
;
j
--;
}
break
;
}
...
...
@@ -4883,7 +4883,6 @@ loop: for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
int
k
=
matcher
.
groups
[
groupIndex
+
1
];
int
groupSize
=
k
-
j
;
// If the referenced group didn't match, neither can this
if
(
j
<
0
)
return
false
;
...
...
@@ -4893,7 +4892,6 @@ loop: for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
matcher
.
hitEnd
=
true
;
return
false
;
}
// Check each new char to make sure it matches what the group
// referenced matched last time around
for
(
int
index
=
0
;
index
<
groupSize
;
index
++)
...
...
src/share/classes/java/util/stream/Collectors.java
浏览文件 @
f9ad02d9
...
...
@@ -137,6 +137,11 @@ public final class Collectors {
return
(
u
,
v
)
->
{
throw
new
IllegalStateException
(
String
.
format
(
"Duplicate key %s"
,
u
));
};
}
@SuppressWarnings
(
"unchecked"
)
private
static
<
I
,
R
>
Function
<
I
,
R
>
castingIdentity
()
{
return
i
->
(
R
)
i
;
}
/**
* Simple implementation class for {@code Collector}.
*
...
...
@@ -166,7 +171,7 @@ public final class Collectors {
BiConsumer
<
A
,
T
>
accumulator
,
BinaryOperator
<
A
>
combiner
,
Set
<
Characteristics
>
characteristics
)
{
this
(
supplier
,
accumulator
,
combiner
,
i
->
(
R
)
i
,
characteristics
);
this
(
supplier
,
accumulator
,
combiner
,
castingIdentity
()
,
characteristics
);
}
@Override
...
...
@@ -209,7 +214,7 @@ public final class Collectors {
*/
public
static
<
T
,
C
extends
Collection
<
T
>>
Collector
<
T
,
?,
C
>
toCollection
(
Supplier
<
C
>
collectionFactory
)
{
return
new
CollectorImpl
<>(
collectionFactory
,
Collection:
:
add
,
return
new
CollectorImpl
<>(
collectionFactory
,
Collection
<
T
>
::
add
,
(
r1
,
r2
)
->
{
r1
.
addAll
(
r2
);
return
r1
;
},
CH_ID
);
}
...
...
@@ -1046,30 +1051,23 @@ public final class Collectors {
public
static
<
T
,
D
,
A
>
Collector
<
T
,
?,
Map
<
Boolean
,
D
>>
partitioningBy
(
Predicate
<?
super
T
>
predicate
,
Collector
<?
super
T
,
A
,
D
>
downstream
)
{
@SuppressWarnings
(
"unchecked"
)
BiConsumer
<
D
,
?
super
T
>
downstreamAccumulator
=
(
BiConsumer
<
D
,
?
super
T
>)
downstream
.
accumulator
();
BiConsumer
<
Map
<
Boolean
,
A
>,
T
>
accumulator
=
(
result
,
t
)
->
{
Partition
<
D
>
asPartition
=
((
Partition
<
D
>)
result
);
downstreamAccumulator
.
accept
(
predicate
.
test
(
t
)
?
asPartition
.
forTrue
:
asPartition
.
forFalse
,
t
);
};
BiConsumer
<
A
,
?
super
T
>
downstreamAccumulator
=
downstream
.
accumulator
();
BiConsumer
<
Partition
<
A
>,
T
>
accumulator
=
(
result
,
t
)
->
downstreamAccumulator
.
accept
(
predicate
.
test
(
t
)
?
result
.
forTrue
:
result
.
forFalse
,
t
);
BinaryOperator
<
A
>
op
=
downstream
.
combiner
();
BinaryOperator
<
Map
<
Boolean
,
A
>>
merger
=
(
m1
,
m2
)
->
{
Partition
<
A
>
left
=
(
Partition
<
A
>)
m1
;
Partition
<
A
>
right
=
(
Partition
<
A
>)
m2
;
return
new
Partition
<>(
op
.
apply
(
left
.
forTrue
,
right
.
forTrue
),
BinaryOperator
<
Partition
<
A
>>
merger
=
(
left
,
right
)
->
new
Partition
<>(
op
.
apply
(
left
.
forTrue
,
right
.
forTrue
),
op
.
apply
(
left
.
forFalse
,
right
.
forFalse
));
};
Supplier
<
Map
<
Boolean
,
A
>>
supplier
=
()
->
new
Partition
<>(
downstream
.
supplier
().
get
(),
Supplier
<
Partition
<
A
>>
supplier
=
()
->
new
Partition
<>(
downstream
.
supplier
().
get
(),
downstream
.
supplier
().
get
());
if
(
downstream
.
characteristics
().
contains
(
Collector
.
Characteristics
.
IDENTITY_FINISH
))
{
return
new
CollectorImpl
<>(
supplier
,
accumulator
,
merger
,
CH_ID
);
}
else
{
Function
<
Map
<
Boolean
,
A
>,
Map
<
Boolean
,
D
>>
finisher
=
(
Map
<
Boolean
,
A
>
par
)
->
{
Partition
<
A
>
asAPartition
=
(
Partition
<
A
>)
par
;
return
new
Partition
<>(
downstream
.
finisher
().
apply
(
asAPartition
.
forTrue
),
downstream
.
finisher
().
apply
(
asAPartition
.
forFalse
));
};
Function
<
Partition
<
A
>,
Map
<
Boolean
,
D
>>
finisher
=
par
->
new
Partition
<>(
downstream
.
finisher
().
apply
(
par
.
forTrue
),
downstream
.
finisher
().
apply
(
par
.
forFalse
));
return
new
CollectorImpl
<>(
supplier
,
accumulator
,
merger
,
finisher
,
CH_NOID
);
}
}
...
...
src/share/classes/java/util/stream/DistinctOps.java
浏览文件 @
f9ad02d9
...
...
@@ -101,7 +101,7 @@ final class DistinctOps {
if
(
StreamOpFlag
.
DISTINCT
.
isKnown
(
flags
))
{
return
sink
;
}
else
if
(
StreamOpFlag
.
SORTED
.
isKnown
(
flags
))
{
return
new
Sink
.
ChainedReference
<
T
>(
sink
)
{
return
new
Sink
.
ChainedReference
<
T
,
T
>(
sink
)
{
boolean
seenNull
;
T
lastSeen
;
...
...
@@ -132,7 +132,7 @@ final class DistinctOps {
}
};
}
else
{
return
new
Sink
.
ChainedReference
<
T
>(
sink
)
{
return
new
Sink
.
ChainedReference
<
T
,
T
>(
sink
)
{
Set
<
T
>
seen
;
@Override
...
...
src/share/classes/java/util/stream/DoublePipeline.java
浏览文件 @
f9ad02d9
...
...
@@ -191,7 +191,7 @@ abstract class DoublePipeline<E_IN>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
Double
>
opWrapSink
(
int
flags
,
Sink
<
Double
>
sink
)
{
return
new
Sink
.
ChainedDouble
(
sink
)
{
return
new
Sink
.
ChainedDouble
<
Double
>
(
sink
)
{
@Override
public
void
accept
(
double
t
)
{
downstream
.
accept
(
mapper
.
applyAsDouble
(
t
));
...
...
@@ -208,9 +208,8 @@ abstract class DoublePipeline<E_IN>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
Double
>
opWrapSink
(
int
flags
,
Sink
<
U
>
sink
)
{
return
new
Sink
.
ChainedDouble
(
sink
)
{
return
new
Sink
.
ChainedDouble
<
U
>
(
sink
)
{
@Override
@SuppressWarnings
(
"unchecked"
)
public
void
accept
(
double
t
)
{
downstream
.
accept
(
mapper
.
apply
(
t
));
}
...
...
@@ -226,7 +225,7 @@ abstract class DoublePipeline<E_IN>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
Double
>
opWrapSink
(
int
flags
,
Sink
<
Integer
>
sink
)
{
return
new
Sink
.
ChainedDouble
(
sink
)
{
return
new
Sink
.
ChainedDouble
<
Integer
>
(
sink
)
{
@Override
public
void
accept
(
double
t
)
{
downstream
.
accept
(
mapper
.
applyAsInt
(
t
));
...
...
@@ -243,7 +242,7 @@ abstract class DoublePipeline<E_IN>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
Double
>
opWrapSink
(
int
flags
,
Sink
<
Long
>
sink
)
{
return
new
Sink
.
ChainedDouble
(
sink
)
{
return
new
Sink
.
ChainedDouble
<
Long
>
(
sink
)
{
@Override
public
void
accept
(
double
t
)
{
downstream
.
accept
(
mapper
.
applyAsLong
(
t
));
...
...
@@ -259,7 +258,7 @@ abstract class DoublePipeline<E_IN>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
|
StreamOpFlag
.
NOT_SIZED
)
{
@Override
Sink
<
Double
>
opWrapSink
(
int
flags
,
Sink
<
Double
>
sink
)
{
return
new
Sink
.
ChainedDouble
(
sink
)
{
return
new
Sink
.
ChainedDouble
<
Double
>
(
sink
)
{
@Override
public
void
begin
(
long
size
)
{
downstream
.
begin
(-
1
);
...
...
@@ -296,7 +295,7 @@ abstract class DoublePipeline<E_IN>
StreamOpFlag
.
NOT_SIZED
)
{
@Override
Sink
<
Double
>
opWrapSink
(
int
flags
,
Sink
<
Double
>
sink
)
{
return
new
Sink
.
ChainedDouble
(
sink
)
{
return
new
Sink
.
ChainedDouble
<
Double
>
(
sink
)
{
@Override
public
void
begin
(
long
size
)
{
downstream
.
begin
(-
1
);
...
...
@@ -319,7 +318,7 @@ abstract class DoublePipeline<E_IN>
0
)
{
@Override
Sink
<
Double
>
opWrapSink
(
int
flags
,
Sink
<
Double
>
sink
)
{
return
new
Sink
.
ChainedDouble
(
sink
)
{
return
new
Sink
.
ChainedDouble
<
Double
>
(
sink
)
{
@Override
public
void
accept
(
double
t
)
{
consumer
.
accept
(
t
);
...
...
src/share/classes/java/util/stream/IntPipeline.java
浏览文件 @
f9ad02d9
...
...
@@ -189,9 +189,8 @@ abstract class IntPipeline<E_IN>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
Integer
>
opWrapSink
(
int
flags
,
Sink
<
Long
>
sink
)
{
return
new
Sink
.
ChainedInt
(
sink
)
{
return
new
Sink
.
ChainedInt
<
Long
>
(
sink
)
{
@Override
@SuppressWarnings
(
"unchecked"
)
public
void
accept
(
int
t
)
{
downstream
.
accept
((
long
)
t
);
}
...
...
@@ -206,9 +205,8 @@ abstract class IntPipeline<E_IN>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
Integer
>
opWrapSink
(
int
flags
,
Sink
<
Double
>
sink
)
{
return
new
Sink
.
ChainedInt
(
sink
)
{
return
new
Sink
.
ChainedInt
<
Double
>
(
sink
)
{
@Override
@SuppressWarnings
(
"unchecked"
)
public
void
accept
(
int
t
)
{
downstream
.
accept
((
double
)
t
);
}
...
...
@@ -229,7 +227,7 @@ abstract class IntPipeline<E_IN>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
Integer
>
opWrapSink
(
int
flags
,
Sink
<
Integer
>
sink
)
{
return
new
Sink
.
ChainedInt
(
sink
)
{
return
new
Sink
.
ChainedInt
<
Integer
>
(
sink
)
{
@Override
public
void
accept
(
int
t
)
{
downstream
.
accept
(
mapper
.
applyAsInt
(
t
));
...
...
@@ -246,9 +244,8 @@ abstract class IntPipeline<E_IN>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
Integer
>
opWrapSink
(
int
flags
,
Sink
<
U
>
sink
)
{
return
new
Sink
.
ChainedInt
(
sink
)
{
return
new
Sink
.
ChainedInt
<
U
>
(
sink
)
{
@Override
@SuppressWarnings
(
"unchecked"
)
public
void
accept
(
int
t
)
{
downstream
.
accept
(
mapper
.
apply
(
t
));
}
...
...
@@ -264,7 +261,7 @@ abstract class IntPipeline<E_IN>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
Integer
>
opWrapSink
(
int
flags
,
Sink
<
Long
>
sink
)
{
return
new
Sink
.
ChainedInt
(
sink
)
{
return
new
Sink
.
ChainedInt
<
Long
>
(
sink
)
{
@Override
public
void
accept
(
int
t
)
{
downstream
.
accept
(
mapper
.
applyAsLong
(
t
));
...
...
@@ -281,7 +278,7 @@ abstract class IntPipeline<E_IN>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
Integer
>
opWrapSink
(
int
flags
,
Sink
<
Double
>
sink
)
{
return
new
Sink
.
ChainedInt
(
sink
)
{
return
new
Sink
.
ChainedInt
<
Double
>
(
sink
)
{
@Override
public
void
accept
(
int
t
)
{
downstream
.
accept
(
mapper
.
applyAsDouble
(
t
));
...
...
@@ -297,7 +294,7 @@ abstract class IntPipeline<E_IN>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
|
StreamOpFlag
.
NOT_SIZED
)
{
@Override
Sink
<
Integer
>
opWrapSink
(
int
flags
,
Sink
<
Integer
>
sink
)
{
return
new
Sink
.
ChainedInt
(
sink
)
{
return
new
Sink
.
ChainedInt
<
Integer
>
(
sink
)
{
@Override
public
void
begin
(
long
size
)
{
downstream
.
begin
(-
1
);
...
...
@@ -334,7 +331,7 @@ abstract class IntPipeline<E_IN>
StreamOpFlag
.
NOT_SIZED
)
{
@Override
Sink
<
Integer
>
opWrapSink
(
int
flags
,
Sink
<
Integer
>
sink
)
{
return
new
Sink
.
ChainedInt
(
sink
)
{
return
new
Sink
.
ChainedInt
<
Integer
>
(
sink
)
{
@Override
public
void
begin
(
long
size
)
{
downstream
.
begin
(-
1
);
...
...
@@ -357,7 +354,7 @@ abstract class IntPipeline<E_IN>
0
)
{
@Override
Sink
<
Integer
>
opWrapSink
(
int
flags
,
Sink
<
Integer
>
sink
)
{
return
new
Sink
.
ChainedInt
(
sink
)
{
return
new
Sink
.
ChainedInt
<
Integer
>
(
sink
)
{
@Override
public
void
accept
(
int
t
)
{
consumer
.
accept
(
t
);
...
...
src/share/classes/java/util/stream/LongPipeline.java
浏览文件 @
f9ad02d9
...
...
@@ -186,7 +186,7 @@ abstract class LongPipeline<E_IN>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
Long
>
opWrapSink
(
int
flags
,
Sink
<
Double
>
sink
)
{
return
new
Sink
.
ChainedLong
(
sink
)
{
return
new
Sink
.
ChainedLong
<
Double
>
(
sink
)
{
@Override
public
void
accept
(
long
t
)
{
downstream
.
accept
((
double
)
t
);
...
...
@@ -208,9 +208,8 @@ abstract class LongPipeline<E_IN>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
Long
>
opWrapSink
(
int
flags
,
Sink
<
Long
>
sink
)
{
return
new
Sink
.
ChainedLong
(
sink
)
{
return
new
Sink
.
ChainedLong
<
Long
>
(
sink
)
{
@Override
@SuppressWarnings
(
"unchecked"
)
public
void
accept
(
long
t
)
{
downstream
.
accept
(
mapper
.
applyAsLong
(
t
));
}
...
...
@@ -226,9 +225,8 @@ abstract class LongPipeline<E_IN>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
Long
>
opWrapSink
(
int
flags
,
Sink
<
U
>
sink
)
{
return
new
Sink
.
ChainedLong
(
sink
)
{
return
new
Sink
.
ChainedLong
<
U
>
(
sink
)
{
@Override
@SuppressWarnings
(
"unchecked"
)
public
void
accept
(
long
t
)
{
downstream
.
accept
(
mapper
.
apply
(
t
));
}
...
...
@@ -244,9 +242,8 @@ abstract class LongPipeline<E_IN>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
Long
>
opWrapSink
(
int
flags
,
Sink
<
Integer
>
sink
)
{
return
new
Sink
.
ChainedLong
(
sink
)
{
return
new
Sink
.
ChainedLong
<
Integer
>
(
sink
)
{
@Override
@SuppressWarnings
(
"unchecked"
)
public
void
accept
(
long
t
)
{
downstream
.
accept
(
mapper
.
applyAsInt
(
t
));
}
...
...
@@ -262,7 +259,7 @@ abstract class LongPipeline<E_IN>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
Long
>
opWrapSink
(
int
flags
,
Sink
<
Double
>
sink
)
{
return
new
Sink
.
ChainedLong
(
sink
)
{
return
new
Sink
.
ChainedLong
<
Double
>
(
sink
)
{
@Override
public
void
accept
(
long
t
)
{
downstream
.
accept
(
mapper
.
applyAsDouble
(
t
));
...
...
@@ -278,7 +275,7 @@ abstract class LongPipeline<E_IN>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
|
StreamOpFlag
.
NOT_SIZED
)
{
@Override
Sink
<
Long
>
opWrapSink
(
int
flags
,
Sink
<
Long
>
sink
)
{
return
new
Sink
.
ChainedLong
(
sink
)
{
return
new
Sink
.
ChainedLong
<
Long
>
(
sink
)
{
@Override
public
void
begin
(
long
size
)
{
downstream
.
begin
(-
1
);
...
...
@@ -315,7 +312,7 @@ abstract class LongPipeline<E_IN>
StreamOpFlag
.
NOT_SIZED
)
{
@Override
Sink
<
Long
>
opWrapSink
(
int
flags
,
Sink
<
Long
>
sink
)
{
return
new
Sink
.
ChainedLong
(
sink
)
{
return
new
Sink
.
ChainedLong
<
Long
>
(
sink
)
{
@Override
public
void
begin
(
long
size
)
{
downstream
.
begin
(-
1
);
...
...
@@ -338,7 +335,7 @@ abstract class LongPipeline<E_IN>
0
)
{
@Override
Sink
<
Long
>
opWrapSink
(
int
flags
,
Sink
<
Long
>
sink
)
{
return
new
Sink
.
ChainedLong
(
sink
)
{
return
new
Sink
.
ChainedLong
<
Long
>
(
sink
)
{
@Override
public
void
accept
(
long
t
)
{
consumer
.
accept
(
t
);
...
...
src/share/classes/java/util/stream/ReferencePipeline.java
浏览文件 @
f9ad02d9
...
...
@@ -163,17 +163,16 @@ abstract class ReferencePipeline<P_IN, P_OUT>
StreamOpFlag
.
NOT_SIZED
)
{
@Override
Sink
<
P_OUT
>
opWrapSink
(
int
flags
,
Sink
<
P_OUT
>
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
>(
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
,
P_OUT
>(
sink
)
{
@Override
public
void
begin
(
long
size
)
{
downstream
.
begin
(-
1
);
}
@Override
@SuppressWarnings
(
"unchecked"
)
public
void
accept
(
P_OUT
u
)
{
if
(
predicate
.
test
(
u
))
downstream
.
accept
(
(
Object
)
u
);
downstream
.
accept
(
u
);
}
};
}
...
...
@@ -188,7 +187,7 @@ abstract class ReferencePipeline<P_IN, P_OUT>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
P_OUT
>
opWrapSink
(
int
flags
,
Sink
<
R
>
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
>(
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
,
R
>(
sink
)
{
@Override
public
void
accept
(
P_OUT
u
)
{
downstream
.
accept
(
mapper
.
apply
(
u
));
...
...
@@ -205,7 +204,7 @@ abstract class ReferencePipeline<P_IN, P_OUT>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
P_OUT
>
opWrapSink
(
int
flags
,
Sink
<
Integer
>
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
>(
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
,
Integer
>(
sink
)
{
@Override
public
void
accept
(
P_OUT
u
)
{
downstream
.
accept
(
mapper
.
applyAsInt
(
u
));
...
...
@@ -222,7 +221,7 @@ abstract class ReferencePipeline<P_IN, P_OUT>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
P_OUT
>
opWrapSink
(
int
flags
,
Sink
<
Long
>
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
>(
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
,
Long
>(
sink
)
{
@Override
public
void
accept
(
P_OUT
u
)
{
downstream
.
accept
(
mapper
.
applyAsLong
(
u
));
...
...
@@ -239,7 +238,7 @@ abstract class ReferencePipeline<P_IN, P_OUT>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
)
{
@Override
Sink
<
P_OUT
>
opWrapSink
(
int
flags
,
Sink
<
Double
>
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
>(
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
,
Double
>(
sink
)
{
@Override
public
void
accept
(
P_OUT
u
)
{
downstream
.
accept
(
mapper
.
applyAsDouble
(
u
));
...
...
@@ -257,14 +256,13 @@ abstract class ReferencePipeline<P_IN, P_OUT>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
|
StreamOpFlag
.
NOT_SIZED
)
{
@Override
Sink
<
P_OUT
>
opWrapSink
(
int
flags
,
Sink
<
R
>
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
>(
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
,
R
>(
sink
)
{
@Override
public
void
begin
(
long
size
)
{
downstream
.
begin
(-
1
);
}
@Override
@SuppressWarnings
(
"unchecked"
)
public
void
accept
(
P_OUT
u
)
{
// We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
Stream
<?
extends
R
>
result
=
mapper
.
apply
(
u
);
...
...
@@ -284,7 +282,7 @@ abstract class ReferencePipeline<P_IN, P_OUT>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
|
StreamOpFlag
.
NOT_SIZED
)
{
@Override
Sink
<
P_OUT
>
opWrapSink
(
int
flags
,
Sink
<
Integer
>
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
>(
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
,
Integer
>(
sink
)
{
IntConsumer
downstreamAsInt
=
downstream:
:
accept
;
@Override
public
void
begin
(
long
size
)
{
...
...
@@ -311,7 +309,7 @@ abstract class ReferencePipeline<P_IN, P_OUT>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
|
StreamOpFlag
.
NOT_SIZED
)
{
@Override
Sink
<
P_OUT
>
opWrapSink
(
int
flags
,
Sink
<
Double
>
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
>(
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
,
Double
>(
sink
)
{
DoubleConsumer
downstreamAsDouble
=
downstream:
:
accept
;
@Override
public
void
begin
(
long
size
)
{
...
...
@@ -338,7 +336,7 @@ abstract class ReferencePipeline<P_IN, P_OUT>
StreamOpFlag
.
NOT_SORTED
|
StreamOpFlag
.
NOT_DISTINCT
|
StreamOpFlag
.
NOT_SIZED
)
{
@Override
Sink
<
P_OUT
>
opWrapSink
(
int
flags
,
Sink
<
Long
>
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
>(
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
,
Long
>(
sink
)
{
LongConsumer
downstreamAsLong
=
downstream:
:
accept
;
@Override
public
void
begin
(
long
size
)
{
...
...
@@ -364,9 +362,8 @@ abstract class ReferencePipeline<P_IN, P_OUT>
0
)
{
@Override
Sink
<
P_OUT
>
opWrapSink
(
int
flags
,
Sink
<
P_OUT
>
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
>(
sink
)
{
return
new
Sink
.
ChainedReference
<
P_OUT
,
P_OUT
>(
sink
)
{
@Override
@SuppressWarnings
(
"unchecked"
)
public
void
accept
(
P_OUT
u
)
{
tee
.
accept
(
u
);
downstream
.
accept
(
u
);
...
...
@@ -495,6 +492,7 @@ abstract class ReferencePipeline<P_IN, P_OUT>
}
@Override
@SuppressWarnings
(
"unchecked"
)
public
final
<
R
,
A
>
R
collect
(
Collector
<?
super
P_OUT
,
A
,
?
extends
R
>
collector
)
{
A
container
;
if
(
isParallel
()
...
...
src/share/classes/java/util/stream/Sink.java
浏览文件 @
f9ad02d9
...
...
@@ -241,11 +241,10 @@ interface Sink<T> extends Consumer<T> {
* implementation of the {@code accept()} method must call the correct
* {@code accept()} method on the downstream {@code Sink}.
*/
static
abstract
class
ChainedReference
<
T
>
implements
Sink
<
T
>
{
@SuppressWarnings
(
"rawtypes"
)
protected
final
Sink
downstream
;
static
abstract
class
ChainedReference
<
T
,
E_OUT
>
implements
Sink
<
T
>
{
protected
final
Sink
<?
super
E_OUT
>
downstream
;
public
ChainedReference
(
Sink
downstream
)
{
public
ChainedReference
(
Sink
<?
super
E_OUT
>
downstream
)
{
this
.
downstream
=
Objects
.
requireNonNull
(
downstream
);
}
...
...
@@ -274,11 +273,10 @@ interface Sink<T> extends Consumer<T> {
* The implementation of the {@code accept()} method must call the correct
* {@code accept()} method on the downstream {@code Sink}.
*/
static
abstract
class
ChainedInt
implements
Sink
.
OfInt
{
@SuppressWarnings
(
"rawtypes"
)
protected
final
Sink
downstream
;
static
abstract
class
ChainedInt
<
E_OUT
>
implements
Sink
.
OfInt
{
protected
final
Sink
<?
super
E_OUT
>
downstream
;
public
ChainedInt
(
Sink
downstream
)
{
public
ChainedInt
(
Sink
<?
super
E_OUT
>
downstream
)
{
this
.
downstream
=
Objects
.
requireNonNull
(
downstream
);
}
...
...
@@ -307,11 +305,10 @@ interface Sink<T> extends Consumer<T> {
* The implementation of the {@code accept()} method must call the correct
* {@code accept()} method on the downstream {@code Sink}.
*/
static
abstract
class
ChainedLong
implements
Sink
.
OfLong
{
@SuppressWarnings
(
"rawtypes"
)
protected
final
Sink
downstream
;
static
abstract
class
ChainedLong
<
E_OUT
>
implements
Sink
.
OfLong
{
protected
final
Sink
<?
super
E_OUT
>
downstream
;
public
ChainedLong
(
Sink
downstream
)
{
public
ChainedLong
(
Sink
<?
super
E_OUT
>
downstream
)
{
this
.
downstream
=
Objects
.
requireNonNull
(
downstream
);
}
...
...
@@ -340,11 +337,10 @@ interface Sink<T> extends Consumer<T> {
* The implementation of the {@code accept()} method must call the correct
* {@code accept()} method on the downstream {@code Sink}.
*/
static
abstract
class
ChainedDouble
implements
Sink
.
OfDouble
{
@SuppressWarnings
(
"rawtypes"
)
protected
final
Sink
downstream
;
static
abstract
class
ChainedDouble
<
E_OUT
>
implements
Sink
.
OfDouble
{
protected
final
Sink
<?
super
E_OUT
>
downstream
;
public
ChainedDouble
(
Sink
downstream
)
{
public
ChainedDouble
(
Sink
<?
super
E_OUT
>
downstream
)
{
this
.
downstream
=
Objects
.
requireNonNull
(
downstream
);
}
...
...
src/share/classes/java/util/stream/SliceOps.java
浏览文件 @
f9ad02d9
...
...
@@ -96,6 +96,11 @@ final class SliceOps {
}
}
@SuppressWarnings
(
"unchecked"
)
private
static
<
T
>
IntFunction
<
T
[]>
castingArray
()
{
return
size
->
(
T
[])
new
Object
[
size
];
}
/**
* Appends a "slice" operation to the provided stream. The slice operation
* may be may be skip-only, limit-only, or skip-and-limit.
...
...
@@ -111,7 +116,7 @@ final class SliceOps {
if
(
skip
<
0
)
throw
new
IllegalArgumentException
(
"Skip must be non-negative: "
+
skip
);
return
new
ReferencePipeline
.
StatefulOp
<
T
,
T
>(
upstream
,
StreamShape
.
REFERENCE
,
return
new
ReferencePipeline
.
StatefulOp
<
T
,
T
>(
upstream
,
StreamShape
.
REFERENCE
,
flags
(
limit
))
{
Spliterator
<
T
>
unorderedSkipLimitSpliterator
(
Spliterator
<
T
>
s
,
long
skip
,
long
limit
,
long
sizeIfKnown
)
{
...
...
@@ -146,7 +151,7 @@ final class SliceOps {
// cancellation will be more aggressive cancelling later tasks
// if the target slice size has been reached from a given task,
// cancellation should also clear local results if any
return
new
SliceTask
<>(
this
,
helper
,
spliterator
,
i
->
(
T
[])
new
Object
[
i
]
,
skip
,
limit
).
return
new
SliceTask
<>(
this
,
helper
,
spliterator
,
castingArray
()
,
skip
,
limit
).
invoke
().
spliterator
();
}
}
...
...
@@ -182,7 +187,7 @@ final class SliceOps {
@Override
Sink
<
T
>
opWrapSink
(
int
flags
,
Sink
<
T
>
sink
)
{
return
new
Sink
.
ChainedReference
<
T
>(
sink
)
{
return
new
Sink
.
ChainedReference
<
T
,
T
>(
sink
)
{
long
n
=
skip
;
long
m
=
limit
>=
0
?
limit
:
Long
.
MAX_VALUE
;
...
...
@@ -291,7 +296,7 @@ final class SliceOps {
@Override
Sink
<
Integer
>
opWrapSink
(
int
flags
,
Sink
<
Integer
>
sink
)
{
return
new
Sink
.
ChainedInt
(
sink
)
{
return
new
Sink
.
ChainedInt
<
Integer
>
(
sink
)
{
long
n
=
skip
;
long
m
=
limit
>=
0
?
limit
:
Long
.
MAX_VALUE
;
...
...
@@ -400,7 +405,7 @@ final class SliceOps {
@Override
Sink
<
Long
>
opWrapSink
(
int
flags
,
Sink
<
Long
>
sink
)
{
return
new
Sink
.
ChainedLong
(
sink
)
{
return
new
Sink
.
ChainedLong
<
Long
>
(
sink
)
{
long
n
=
skip
;
long
m
=
limit
>=
0
?
limit
:
Long
.
MAX_VALUE
;
...
...
@@ -509,7 +514,7 @@ final class SliceOps {
@Override
Sink
<
Double
>
opWrapSink
(
int
flags
,
Sink
<
Double
>
sink
)
{
return
new
Sink
.
ChainedDouble
(
sink
)
{
return
new
Sink
.
ChainedDouble
<
Double
>
(
sink
)
{
long
n
=
skip
;
long
m
=
limit
>=
0
?
limit
:
Long
.
MAX_VALUE
;
...
...
@@ -560,13 +565,13 @@ final class SliceOps {
private
volatile
boolean
completed
;
SliceTask
(
AbstractPipeline
<
?
,
P_OUT
,
?>
op
,
SliceTask
(
AbstractPipeline
<
P_OUT
,
P_OUT
,
?>
op
,
PipelineHelper
<
P_OUT
>
helper
,
Spliterator
<
P_IN
>
spliterator
,
IntFunction
<
P_OUT
[]>
generator
,
long
offset
,
long
size
)
{
super
(
helper
,
spliterator
);
this
.
op
=
(
AbstractPipeline
<
P_OUT
,
P_OUT
,
?>)
op
;
this
.
op
=
op
;
this
.
generator
=
generator
;
this
.
targetOffset
=
offset
;
this
.
targetSize
=
size
;
...
...
src/share/classes/java/util/stream/SortedOps.java
浏览文件 @
f9ad02d9
...
...
@@ -129,7 +129,7 @@ final class SortedOps {
}
@Override
public
Sink
<
T
>
opWrapSink
(
int
flags
,
Sink
sink
)
{
public
Sink
<
T
>
opWrapSink
(
int
flags
,
Sink
<
T
>
sink
)
{
Objects
.
requireNonNull
(
sink
);
// If the input is already naturally sorted and this operation
...
...
@@ -280,12 +280,12 @@ final class SortedOps {
/**
* {@link ForkJoinTask} for implementing sort on SIZED reference streams.
*/
private
static
final
class
SizedRefSortingSink
<
T
>
extends
Sink
.
ChainedReference
<
T
>
{
private
static
final
class
SizedRefSortingSink
<
T
>
extends
Sink
.
ChainedReference
<
T
,
T
>
{
private
final
Comparator
<?
super
T
>
comparator
;
private
T
[]
array
;
private
int
offset
;
SizedRefSortingSink
(
Sink
<
T
>
sink
,
Comparator
<?
super
T
>
comparator
)
{
SizedRefSortingSink
(
Sink
<
?
super
T
>
sink
,
Comparator
<?
super
T
>
comparator
)
{
super
(
sink
);
this
.
comparator
=
comparator
;
}
...
...
@@ -320,11 +320,11 @@ final class SortedOps {
/**
* {@link Sink} for implementing sort on reference streams.
*/
private
static
final
class
RefSortingSink
<
T
>
extends
Sink
.
ChainedReference
<
T
>
{
private
static
final
class
RefSortingSink
<
T
>
extends
Sink
.
ChainedReference
<
T
,
T
>
{
private
final
Comparator
<?
super
T
>
comparator
;
private
ArrayList
<
T
>
list
;
RefSortingSink
(
Sink
<
T
>
sink
,
Comparator
<?
super
T
>
comparator
)
{
RefSortingSink
(
Sink
<
?
super
T
>
sink
,
Comparator
<?
super
T
>
comparator
)
{
super
(
sink
);
this
.
comparator
=
comparator
;
}
...
...
@@ -352,11 +352,11 @@ final class SortedOps {
/**
* {@link Sink} for implementing sort on SIZED int streams.
*/
private
static
final
class
SizedIntSortingSink
extends
Sink
.
ChainedInt
{
private
static
final
class
SizedIntSortingSink
extends
Sink
.
ChainedInt
<
Integer
>
{
private
int
[]
array
;
private
int
offset
;
SizedIntSortingSink
(
Sink
downstream
)
{
SizedIntSortingSink
(
Sink
<?
super
Integer
>
downstream
)
{
super
(
downstream
);
}
...
...
@@ -386,10 +386,10 @@ final class SortedOps {
/**
* {@link Sink} for implementing sort on int streams.
*/
private
static
final
class
IntSortingSink
extends
Sink
.
ChainedInt
{
private
static
final
class
IntSortingSink
extends
Sink
.
ChainedInt
<
Integer
>
{
private
SpinedBuffer
.
OfInt
b
;
IntSortingSink
(
Sink
sink
)
{
IntSortingSink
(
Sink
<?
super
Integer
>
sink
)
{
super
(
sink
);
}
...
...
@@ -417,11 +417,11 @@ final class SortedOps {
/**
* {@link Sink} for implementing sort on SIZED long streams.
*/
private
static
final
class
SizedLongSortingSink
extends
Sink
.
ChainedLong
{
private
static
final
class
SizedLongSortingSink
extends
Sink
.
ChainedLong
<
Long
>
{
private
long
[]
array
;
private
int
offset
;
SizedLongSortingSink
(
Sink
downstream
)
{
SizedLongSortingSink
(
Sink
<?
super
Long
>
downstream
)
{
super
(
downstream
);
}
...
...
@@ -451,10 +451,10 @@ final class SortedOps {
/**
* {@link Sink} for implementing sort on long streams.
*/
private
static
final
class
LongSortingSink
extends
Sink
.
ChainedLong
{
private
static
final
class
LongSortingSink
extends
Sink
.
ChainedLong
<
Long
>
{
private
SpinedBuffer
.
OfLong
b
;
LongSortingSink
(
Sink
sink
)
{
LongSortingSink
(
Sink
<?
super
Long
>
sink
)
{
super
(
sink
);
}
...
...
@@ -482,11 +482,11 @@ final class SortedOps {
/**
* {@link Sink} for implementing sort on SIZED double streams.
*/
private
static
final
class
SizedDoubleSortingSink
extends
Sink
.
ChainedDouble
{
private
static
final
class
SizedDoubleSortingSink
extends
Sink
.
ChainedDouble
<
Double
>
{
private
double
[]
array
;
private
int
offset
;
SizedDoubleSortingSink
(
Sink
downstream
)
{
SizedDoubleSortingSink
(
Sink
<?
super
Double
>
downstream
)
{
super
(
downstream
);
}
...
...
@@ -516,10 +516,10 @@ final class SortedOps {
/**
* {@link Sink} for implementing sort on double streams.
*/
private
static
final
class
DoubleSortingSink
extends
Sink
.
ChainedDouble
{
private
static
final
class
DoubleSortingSink
extends
Sink
.
ChainedDouble
<
Double
>
{
private
SpinedBuffer
.
OfDouble
b
;
DoubleSortingSink
(
Sink
sink
)
{
DoubleSortingSink
(
Sink
<?
super
Double
>
sink
)
{
super
(
sink
);
}
...
...
src/share/classes/java/util/zip/ZipOutputStream.java
浏览文件 @
f9ad02d9
...
...
@@ -663,6 +663,9 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
while
(
off
+
4
<=
len
)
{
int
tag
=
get16
(
extra
,
off
);
int
sz
=
get16
(
extra
,
off
+
2
);
if
(
sz
<
0
||
(
off
+
4
+
sz
)
>
len
)
{
break
;
}
if
(
tag
==
EXTID_EXTT
||
tag
==
EXTID_ZIP64
)
{
skipped
+=
(
sz
+
4
);
}
...
...
@@ -684,11 +687,18 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
while
(
off
+
4
<=
len
)
{
int
tag
=
get16
(
extra
,
off
);
int
sz
=
get16
(
extra
,
off
+
2
);
if
(
sz
<
0
||
(
off
+
4
+
sz
)
>
len
)
{
writeBytes
(
extra
,
off
,
len
-
off
);
return
;
}
if
(
tag
!=
EXTID_EXTT
&&
tag
!=
EXTID_ZIP64
)
{
writeBytes
(
extra
,
off
,
sz
+
4
);
}
off
+=
(
sz
+
4
);
}
if
(
off
<
len
)
{
writeBytes
(
extra
,
off
,
len
-
off
);
}
}
}
...
...
src/share/classes/javax/net/ssl/SNIHostName.java
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012,
2013,
Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -293,6 +293,7 @@ public final class SNIHostName extends SNIServerName {
* the <a href="{@docRoot}/java/util/regex/Pattern.html#sum">
* regular expression pattern</a>
* representing the hostname(s) to match
* @return a {@code SNIMatcher} object for {@code SNIHostName}s
* @throws NullPointerException if {@code regex} is
* {@code null}
* @throws java.util.regex.PatternSyntaxException if the regular expression's
...
...
src/share/classes/javax/net/ssl/X509KeyManager.java
浏览文件 @
f9ad02d9
/*
* Copyright (c) 1999, 20
04
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 20
13
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -40,7 +40,7 @@ import java.net.Socket;
* <UL>
* <LI> determine the set of aliases that are available for negotiations
* based on the criteria presented,
* <LI> select the <
ITALIC> best alias </ITALIC
> based on
* <LI> select the <
i> best alias</i
> based on
* the criteria presented, and
* <LI> obtain the corresponding key material for given aliases.
* </UL>
...
...
src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java
浏览文件 @
f9ad02d9
...
...
@@ -197,8 +197,7 @@ public final class KerberosPrincipal
* {@code KerberosPrincipal} and the two
* {@code KerberosPrincipal} instances are equivalent.
* More formally two {@code KerberosPrincipal} instances are equal
* if the values returned by {@code getName()} are equal and the
* values returned by {@code getNameType()} are equal.
* if the values returned by {@code getName()} are equal.
*
* @param other the Object to compare to
* @return true if the Object passed in represents the same principal
...
...
@@ -211,15 +210,10 @@ public final class KerberosPrincipal
if
(!
(
other
instanceof
KerberosPrincipal
))
{
return
false
;
}
else
{
}
String
myFullName
=
getName
();
String
otherFullName
=
((
KerberosPrincipal
)
other
).
getName
();
if
(
nameType
==
((
KerberosPrincipal
)
other
).
nameType
&&
myFullName
.
equals
(
otherFullName
))
{
return
true
;
}
}
return
false
;
return
myFullName
.
equals
(
otherFullName
);
}
/**
...
...
src/share/classes/sun/nio/ch/AbstractPollSelectorImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -193,9 +193,4 @@ abstract class AbstractPollSelectorImpl
if
(!
selch
.
isOpen
()
&&
!
selch
.
isRegistered
())
((
SelChImpl
)
selch
).
kill
();
}
static
{
Util
.
load
();
}
}
src/share/classes/sun/nio/ch/DatagramChannelImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -1138,7 +1138,7 @@ class DatagramChannelImpl
throws
IOException
;
static
{
Util
.
load
();
IO
Util
.
load
();
initIDs
();
}
...
...
src/share/classes/sun/nio/ch/FileChannelImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -1162,7 +1162,7 @@ public class FileChannelImpl
private
static
native
long
initIDs
();
static
{
Util
.
load
();
IO
Util
.
load
();
allocationGranularity
=
initIDs
();
}
...
...
src/share/classes/sun/nio/ch/IOUtil.java
浏览文件 @
f9ad02d9
...
...
@@ -347,9 +347,23 @@ public class IOUtil {
static
native
void
initIDs
();
/**
* Used to trigger loading of native libraries
*/
public
static
void
load
()
{
}
static
{
// Note that IOUtil.initIDs is called from within Util.load.
Util
.
load
();
java
.
security
.
AccessController
.
doPrivileged
(
new
java
.
security
.
PrivilegedAction
<
Void
>()
{
public
Void
run
()
{
System
.
loadLibrary
(
"net"
);
System
.
loadLibrary
(
"nio"
);
return
null
;
}
});
initIDs
();
IOV_MAX
=
iovMax
();
}
...
...
src/share/classes/sun/nio/ch/Net.java
浏览文件 @
f9ad02d9
...
...
@@ -582,7 +582,7 @@ public class Net {
private
static
native
void
initIDs
();
static
{
Util
.
load
();
IO
Util
.
load
();
initIDs
();
}
...
...
src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -416,7 +416,7 @@ class ServerSocketChannelImpl
private
static
native
void
initIDs
();
static
{
Util
.
load
();
IO
Util
.
load
();
initIDs
();
nd
=
new
SocketDispatcher
();
}
...
...
src/share/classes/sun/nio/ch/SocketChannelImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -1024,7 +1024,7 @@ class SocketChannelImpl
throws
IOException
;
static
{
Util
.
load
();
IO
Util
.
load
();
nd
=
new
SocketDispatcher
();
}
...
...
src/share/classes/sun/nio/ch/Util.java
浏览文件 @
f9ad02d9
...
...
@@ -401,30 +401,4 @@ public class Util {
return
bugLevel
.
equals
(
bl
);
}
// -- Initialization --
private
static
boolean
loaded
=
false
;
public
static
void
load
()
{
synchronized
(
Util
.
class
)
{
if
(
loaded
)
return
;
loaded
=
true
;
java
.
security
.
AccessController
.
doPrivileged
(
new
java
.
security
.
PrivilegedAction
<
Void
>()
{
public
Void
run
()
{
System
.
loadLibrary
(
"net"
);
System
.
loadLibrary
(
"nio"
);
return
null
;
}
});
// IOUtil must be initialized; Its native methods are called from
// other places in native nio code so they must be set up.
IOUtil
.
initIDs
();
}
}
}
src/share/classes/sun/tools/jconsole/ConnectDialog.java
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2004, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -268,8 +268,13 @@ public class ConnectDialog extends InternalDialog
public
void
revalidate
()
{
// Adjust some colors
Color
disabledForeground
=
UIManager
.
getColor
(
"Label.disabledForeground"
);
if
(
disabledForeground
==
null
)
{
// fall back for Nimbus that doesn't support 'Label.disabledForeground'
disabledForeground
=
UIManager
.
getColor
(
"Label.disabledText"
);
}
hintTextColor
=
ensureContrast
(
UIManager
.
getColor
(
"Label.disabledForeground"
)
,
ensureContrast
(
disabledForeground
,
UIManager
.
getColor
(
"Panel.background"
));
disabledTableCellColor
=
ensureContrast
(
new
Color
(
0x808080
),
...
...
src/share/classes/sun/tools/jconsole/JConsole.java
浏览文件 @
f9ad02d9
...
...
@@ -858,6 +858,10 @@ public class JConsole extends JFrame
try
{
updateInterval
=
Integer
.
parseInt
(
arg
.
substring
(
10
))
*
1000
;
if
(
updateInterval
<=
0
)
{
usage
();
return
;
}
}
catch
(
NumberFormatException
ex
)
{
usage
();
return
;
...
...
src/share/classes/sun/tools/jconsole/Messages.java
浏览文件 @
f9ad02d9
/*
* Copyright (c) 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -146,7 +146,6 @@ final public class Messages {
public
static
String
HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME
;
public
static
String
HELP_ABOUT_DIALOG_MASTHEAD_TITLE
;
public
static
String
HELP_ABOUT_DIALOG_TITLE
;
public
static
String
HELP_ABOUT_DIALOG_USER_GUIDE_LINK
;
public
static
String
HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL
;
public
static
String
HELP_MENU_ABOUT_TITLE
;
public
static
String
HELP_MENU_USER_GUIDE_TITLE
;
...
...
@@ -272,6 +271,7 @@ final public class Messages {
public
static
String
THREADS
;
public
static
String
THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME
;
public
static
String
THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME
;
public
static
String
THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE
;
public
static
String
THRESHOLD
;
public
static
String
TILE
;
public
static
String
TIME_RANGE_COLON
;
...
...
src/share/classes/sun/tools/jconsole/Plotter.java
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2004, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -337,6 +337,13 @@ public class Plotter extends JComponent
public
void
paintComponent
(
Graphics
g
)
{
super
.
paintComponent
(
g
);
int
width
=
getWidth
()-
rightMargin
-
leftMargin
-
10
;
int
height
=
getHeight
()-
topMargin
-
bottomMargin
;
if
(
width
<=
0
||
height
<=
0
)
{
// not enough room to paint anything
return
;
}
Color
oldColor
=
g
.
getColor
();
Font
oldFont
=
g
.
getFont
();
Color
fg
=
getForeground
();
...
...
src/share/classes/sun/tools/jconsole/ThreadTab.java
浏览文件 @
f9ad02d9
...
...
@@ -595,6 +595,8 @@ class ThreadTab extends Tab implements ActionListener, DocumentListener, ListSel
setBorder
(
thinEmptyBorder
);
setSelectionMode
(
ListSelectionModel
.
SINGLE_SELECTION
);
textArea
.
setText
(
Messages
.
THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE
);
addListSelectionListener
(
ThreadTab
.
this
);
setCellRenderer
(
new
DefaultListCellRenderer
()
{
public
Component
getListCellRendererComponent
(
JList
<?>
list
,
Object
value
,
int
index
,
...
...
src/share/classes/sun/tools/jconsole/VMPanel.java
浏览文件 @
f9ad02d9
...
...
@@ -153,9 +153,11 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener {
// in order to reserve space for the connect toggle.
public
void
setUI
(
TabbedPaneUI
ui
)
{
Insets
insets
=
(
Insets
)
UIManager
.
getLookAndFeelDefaults
().
get
(
"TabbedPane.tabAreaInsets"
);
if
(
insets
!=
null
)
{
insets
=
(
Insets
)
insets
.
clone
();
insets
.
right
+=
connectedIcon24
.
getIconWidth
()
+
8
;
UIManager
.
put
(
"TabbedPane.tabAreaInsets"
,
insets
);
}
super
.
setUI
(
ui
);
}
...
...
src/share/classes/sun/tools/jconsole/resources/messages.properties
浏览文件 @
f9ad02d9
...
...
@@ -104,7 +104,6 @@ HELP_ABOUT_DIALOG_JAVA_VERSION=Java VM version:<br>{0}
HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME
=
Masthead Graphic
HELP_ABOUT_DIALOG_MASTHEAD_TITLE
=
About JConsole
HELP_ABOUT_DIALOG_TITLE
=
JConsole: About
HELP_ABOUT_DIALOG_USER_GUIDE_LINK
=
JConsole &User Guide:<br>{0}
HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL
=
http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html
HELP_MENU_ABOUT_TITLE
=
&About JConsole
HELP_MENU_USER_GUIDE_TITLE
=
Online &User Guide
...
...
@@ -230,6 +229,7 @@ SUMMARY_TAB_VM_VERSION={0} version {1}
THREADS
=
Threads
THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME
=
Thread Information
THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME
=
Chart for number of threads.
THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE
=
[No thread selected]
THRESHOLD
=
Threshold
TILE
=
&Tile
TIME_RANGE_COLON
=
&Time Range:
...
...
src/share/classes/sun/tools/jconsole/resources/messages_ja.properties
浏览文件 @
f9ad02d9
...
...
@@ -104,7 +104,6 @@ HELP_ABOUT_DIALOG_JAVA_VERSION=Java VM\u30D0\u30FC\u30B8\u30E7\u30F3:<br>{0}
HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME
=
\u
30DE
\u
30B9
\u
30C8
\u
30D8
\u
30C3
\u
30C9
\u
56F3
\u
5F62
HELP_ABOUT_DIALOG_MASTHEAD_TITLE
=
JConsole
\u
306B
\u3064\u3044\u3066
HELP_ABOUT_DIALOG_TITLE
=
JConsole:
\u
8A73
\u
7D30
HELP_ABOUT_DIALOG_USER_GUIDE_LINK
=
JConsole
\u
30E6
\u
30FC
\u
30B6
\u
30FC
\u
30FB
\u
30AC
\u
30A4
\u
30C9(&U):<br>{0}
HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL
=
http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html
HELP_MENU_ABOUT_TITLE
=
JConsole
\u
306B
\u3064\u3044\u3066
(&A)
HELP_MENU_USER_GUIDE_TITLE
=
\u
30AA
\u
30F3
\u
30E9
\u
30A4
\u
30F3
\u
30FB
\u
30E6
\u
30FC
\u
30B6
\u
30FC
\u
30FB
\u
30AC
\u
30A4
\u
30C9(&U)
...
...
src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties
浏览文件 @
f9ad02d9
...
...
@@ -104,7 +104,6 @@ HELP_ABOUT_DIALOG_JAVA_VERSION=Java VM \u7248\u672C:<br>{0}
HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME
=
\u
62A5
\u5934\u
56FE
HELP_ABOUT_DIALOG_MASTHEAD_TITLE
=
\u5173\u
4E8E JConsole
HELP_ABOUT_DIALOG_TITLE
=
JConsole:
\u5173\u
4E8E
HELP_ABOUT_DIALOG_USER_GUIDE_LINK
=
JConsole
\u7528\u6237\u6307\u5357
(&U):<br>{0}
HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL
=
http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html
HELP_MENU_ABOUT_TITLE
=
\u5173\u
4E8E JConsole(&A)
HELP_MENU_USER_GUIDE_TITLE
=
\u8054\u
673A
\u7528\u6237\u6307\u5357
(&U)
...
...
src/share/lib/security/java.security-linux
浏览文件 @
f9ad02d9
...
...
@@ -181,6 +181,7 @@ package.access=sun.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.proxy.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
...
...
@@ -225,6 +226,7 @@ package.definition=sun.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.proxy.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
...
...
src/share/lib/security/java.security-macosx
浏览文件 @
f9ad02d9
...
...
@@ -182,6 +182,7 @@ package.access=sun.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.proxy.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
...
...
@@ -226,6 +227,7 @@ package.definition=sun.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.proxy.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
...
...
src/share/lib/security/java.security-solaris
浏览文件 @
f9ad02d9
...
...
@@ -183,6 +183,7 @@ package.access=sun.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.proxy.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
...
...
@@ -226,6 +227,7 @@ package.definition=sun.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.proxy.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
...
...
src/share/lib/security/java.security-windows
浏览文件 @
f9ad02d9
...
...
@@ -182,6 +182,7 @@ package.access=sun.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.proxy.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
...
...
@@ -226,6 +227,7 @@ package.definition=sun.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.media.sound.,\
com.sun.proxy.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
...
...
src/share/native/common/check_code.c
浏览文件 @
f9ad02d9
...
...
@@ -90,6 +90,12 @@
#include "classfile_constants.h"
#include "opcodes.in_out"
#ifdef __APPLE__
/* use setjmp/longjmp versions that do not save/restore the signal mask */
#define setjmp _setjmp
#define longjmp _longjmp
#endif
#define MAX_ARRAY_DIMENSIONS 255
/* align byte code */
#ifndef ALIGN_UP
...
...
src/solaris/classes/sun/nio/ch/DatagramDispatcher.java
浏览文件 @
f9ad02d9
...
...
@@ -36,7 +36,7 @@ import java.net.*;
class
DatagramDispatcher
extends
NativeDispatcher
{
static
{
Util
.
load
();
IO
Util
.
load
();
}
int
read
(
FileDescriptor
fd
,
long
address
,
int
len
)
throws
IOException
{
...
...
src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java
浏览文件 @
f9ad02d9
...
...
@@ -316,4 +316,8 @@ class DevPollArrayWrapper {
private
native
int
poll0
(
long
pollAddress
,
int
numfds
,
long
timeout
,
int
wfd
);
private
static
native
void
interrupt
(
int
fd
);
static
{
IOUtil
.
load
();
}
}
src/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -196,9 +196,4 @@ class DevPollSelectorImpl
}
return
this
;
}
static
{
Util
.
load
();
}
}
src/solaris/classes/sun/nio/ch/EPoll.java
浏览文件 @
f9ad02d9
...
...
@@ -113,6 +113,6 @@ class EPoll {
throws
IOException
;
static
{
Util
.
load
();
IO
Util
.
load
();
}
}
src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java
浏览文件 @
f9ad02d9
...
...
@@ -318,6 +318,7 @@ class EPollArrayWrapper {
}
static
{
IOUtil
.
load
();
init
();
}
...
...
src/solaris/classes/sun/nio/ch/EPollPort.java
浏览文件 @
f9ad02d9
...
...
@@ -318,6 +318,6 @@ final class EPollPort
private
static
native
void
close0
(
int
fd
);
static
{
Util
.
load
();
IO
Util
.
load
();
}
}
src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -196,8 +196,4 @@ class EPollSelectorImpl
}
return
this
;
}
static
{
Util
.
load
();
}
}
src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -31,7 +31,7 @@ class FileDispatcherImpl extends FileDispatcher
{
static
{
Util
.
load
();
IO
Util
.
load
();
init
();
}
...
...
src/solaris/classes/sun/nio/ch/InheritedChannel.java
浏览文件 @
f9ad02d9
...
...
@@ -235,6 +235,6 @@ class InheritedChannel {
private
static
native
int
peerPort0
(
int
fd
);
static
{
Util
.
load
();
IO
Util
.
load
();
}
}
src/solaris/classes/sun/nio/ch/KQueue.java
浏览文件 @
f9ad02d9
...
...
@@ -115,6 +115,6 @@ class KQueue {
throws
IOException
;
static
{
Util
.
load
();
IO
Util
.
load
();
}
}
src/solaris/classes/sun/nio/ch/KQueuePort.java
浏览文件 @
f9ad02d9
...
...
@@ -326,6 +326,6 @@ final class KQueuePort
private
static
native
void
close0
(
int
fd
);
static
{
Util
.
load
();
IO
Util
.
load
();
}
}
src/solaris/classes/sun/nio/ch/NativeThread.java
浏览文件 @
f9ad02d9
...
...
@@ -54,7 +54,7 @@ public class NativeThread {
private
static
native
void
init
();
static
{
Util
.
load
();
IO
Util
.
load
();
init
();
}
...
...
src/solaris/classes/sun/nio/ch/PollArrayWrapper.java
浏览文件 @
f9ad02d9
...
...
@@ -126,4 +126,7 @@ public class PollArrayWrapper extends AbstractPollArrayWrapper {
private
static
native
void
interrupt
(
int
fd
);
static
{
IOUtil
.
load
();
}
}
src/solaris/classes/sun/nio/ch/SinkChannelImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -37,7 +37,7 @@ class SinkChannelImpl
{
// Used to make native read and write calls
private
static
NativeDispatcher
nd
;
private
static
final
NativeDispatcher
nd
=
new
FileDispatcherImpl
()
;
// The file descriptor associated with this channel
FileDescriptor
fd
;
...
...
@@ -206,10 +206,4 @@ class SinkChannelImpl
throw
new
IndexOutOfBoundsException
();
return
write
(
Util
.
subsequence
(
srcs
,
offset
,
length
));
}
static
{
Util
.
load
();
nd
=
new
FileDispatcherImpl
();
}
}
src/solaris/classes/sun/nio/ch/SolarisEventPort.java
浏览文件 @
f9ad02d9
...
...
@@ -260,6 +260,6 @@ class SolarisEventPort
static
{
Util
.
load
();
IO
Util
.
load
();
}
}
src/solaris/classes/sun/nio/ch/SourceChannelImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -37,7 +37,7 @@ class SourceChannelImpl
{
// Used to make native read and write calls
private
static
NativeDispatcher
nd
;
private
static
final
NativeDispatcher
nd
=
new
FileDispatcherImpl
()
;
// The file descriptor associated with this channel
FileDescriptor
fd
;
...
...
@@ -206,10 +206,4 @@ class SourceChannelImpl
}
}
}
static
{
Util
.
load
();
nd
=
new
FileDispatcherImpl
();
}
}
src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -345,7 +345,7 @@ class UnixAsynchronousServerSocketChannelImpl
throws
IOException
;
static
{
Util
.
load
();
IO
Util
.
load
();
initIDs
();
}
}
src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -748,6 +748,6 @@ class UnixAsynchronousSocketChannelImpl
private
static
native
void
checkConnect
(
int
fdVal
)
throws
IOException
;
static
{
Util
.
load
();
IO
Util
.
load
();
}
}
src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -1106,7 +1106,7 @@ public class SctpChannelImpl extends SctpChannel
boolean
ready
)
throws
IOException
;
static
{
Util
.
load
();
/* loads nio & net native libraries */
IO
Util
.
load
();
/* loads nio & net native libraries */
java
.
security
.
AccessController
.
doPrivileged
(
new
java
.
security
.
PrivilegedAction
<
Void
>()
{
public
Void
run
()
{
...
...
src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -995,7 +995,7 @@ public class SctpMultiChannelImpl extends SctpMultiChannel
}
static
{
Util
.
load
();
/* loads nio & net native libraries */
IO
Util
.
load
();
/* loads nio & net native libraries */
java
.
security
.
AccessController
.
doPrivileged
(
new
java
.
security
.
PrivilegedAction
<
Void
>()
{
public
Void
run
()
{
...
...
src/solaris/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -426,7 +426,7 @@ public class SctpServerChannelImpl extends SctpServerChannel
FileDescriptor
newfd
,
InetSocketAddress
[]
isaa
)
throws
IOException
;
static
{
Util
.
load
();
// loads nio & net native libraries
IO
Util
.
load
();
// loads nio & net native libraries
java
.
security
.
AccessController
.
doPrivileged
(
new
java
.
security
.
PrivilegedAction
<
Void
>()
{
public
Void
run
()
{
...
...
src/windows/classes/sun/nio/ch/DatagramDispatcher.java
浏览文件 @
f9ad02d9
...
...
@@ -36,7 +36,7 @@ import java.net.*;
class
DatagramDispatcher
extends
NativeDispatcher
{
static
{
Util
.
load
();
IO
Util
.
load
();
}
int
read
(
FileDescriptor
fd
,
long
address
,
int
len
)
throws
IOException
{
...
...
src/windows/classes/sun/nio/ch/FileDispatcherImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -32,7 +32,7 @@ import sun.misc.JavaIOFileDescriptorAccess;
class
FileDispatcherImpl
extends
FileDispatcher
{
static
{
Util
.
load
();
IO
Util
.
load
();
}
/**
...
...
src/windows/classes/sun/nio/ch/FileKey.java
浏览文件 @
f9ad02d9
...
...
@@ -73,6 +73,7 @@ public class FileKey {
private
static
native
void
initIDs
();
static
{
IOUtil
.
load
();
initIDs
();
}
}
src/windows/classes/sun/nio/ch/Iocp.java
浏览文件 @
f9ad02d9
...
...
@@ -443,7 +443,7 @@ class Iocp extends AsynchronousChannelGroupImpl {
private
static
native
String
getErrorMessage
(
int
error
);
static
{
Util
.
load
();
IO
Util
.
load
();
initIDs
();
// thread agnostic I/O on Vista/2008 or newer
...
...
src/windows/classes/sun/nio/ch/PipeImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -56,7 +56,6 @@ class PipeImpl
private
static
final
Random
rnd
;
static
{
Util
.
load
();
byte
[]
someBytes
=
new
byte
[
8
];
boolean
resultOK
=
IOUtil
.
randomBytes
(
someBytes
);
if
(
resultOK
)
{
...
...
src/windows/classes/sun/nio/ch/SocketDispatcher.java
浏览文件 @
f9ad02d9
...
...
@@ -36,7 +36,7 @@ class SocketDispatcher extends NativeDispatcher
{
static
{
Util
.
load
();
IO
Util
.
load
();
}
int
read
(
FileDescriptor
fd
,
long
address
,
int
len
)
throws
IOException
{
...
...
src/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -750,6 +750,6 @@ public class WindowsAsynchronousFileChannelImpl
private
static
native
void
close0
(
long
handle
);
static
{
Util
.
load
();
IO
Util
.
load
();
}
}
src/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -363,7 +363,7 @@ class WindowsAsynchronousServerSocketChannelImpl
private
static
native
void
closesocket0
(
long
socket
)
throws
IOException
;
static
{
Util
.
load
();
IO
Util
.
load
();
initIDs
();
}
}
src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -919,7 +919,7 @@ class WindowsAsynchronousSocketChannelImpl
private
static
native
void
closesocket0
(
long
socket
)
throws
IOException
;
static
{
Util
.
load
();
IO
Util
.
load
();
initIDs
();
}
}
src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java
浏览文件 @
f9ad02d9
...
...
@@ -611,6 +611,6 @@ final class WindowsSelectorImpl extends SelectorImpl {
}
static
{
Util
.
load
();
IO
Util
.
load
();
}
}
test/ProblemList.txt
浏览文件 @
f9ad02d9
...
...
@@ -208,7 +208,7 @@ sun/net/www/http/HttpClient/ProxyTest.java generic-all
# jdk_io
# 7160013
java/io/File/MaxPathLength.java windows-all
#
java/io/File/MaxPathLength.java windows-all
############################################################################
...
...
@@ -336,12 +336,6 @@ com/sun/jdi/SuspendThreadTest.java generic-all
# Filed 6653793
com/sun/jdi/RedefineCrossEvent.java generic-all
# Filed 6987312
com/sun/jdi/DoubleAgentTest.java generic-all
# Filed 7020857
com/sun/jdi/FieldWatchpoints.java generic-all
# Filed 6402201
com/sun/jdi/ProcessAttachTest.sh generic-all
...
...
test/TEST.ROOT
浏览文件 @
f9ad02d9
...
...
@@ -9,3 +9,6 @@ othervm.dirs=java/awt java/beans java/rmi javax/accessibility javax/imageio java
# Tests that cannot run concurrently
exclusiveAccess.dirs=java/rmi/Naming java/util/Currency java/util/prefs sun/management/jmxremote sun/tools/jstatd sun/security/mscapi
# Group definitions
groups=TEST.groups [closed/TEST.groups]
test/TEST.groups
0 → 100644
浏览文件 @
f9ad02d9
# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
jdk_lang = \
java/lang \
-java/lang/management \
-java/lang/instrument \
sun/invoke \
sun/misc \
sun/reflect \
vm
jdk_util = \
java/util \
sun/util
jdk_math = \
java/math
jdk_io = \
java/io
jdk_nio = \
java/nio \
sun/nio
jdk_net = \
java/net \
com/sun/net \
com/oracle/net \
sun/net
jdk_time = \
java/time
jdk_rmi = \
java/rmi \
javax/rmi/ssl \
sun/rmi
jdk_security1 = \
java/security
jdk_security2 = \
javax/crypto \
javax/xml/crypto \
com/sun/crypto
jdk_security3 = \
javax/security \
com/sun/security \
com/sun/org/apache/xml/internal/security \
com/oracle/security \
sun/security \
lib/security
jdk_security = \
:jdk_security1 \
:jdk_security2 \
:jdk_security3
jdk_text = \
java/text \
sun/text
jdk_management = \
java/lang/management \
com/sun/management \
sun/management
jdk_instrument = \
java/lang/instrument
jdk_jmx = \
javax/management \
com/sun/jmx
jdk_jdi = \
com/sun/jdi
#
# Tool (and tool API) tests are split into core and svc groups
#
core_tools = \
tools \
com/sun/tools/extcheck \
sun/tools/java \
sun/tools/native2ascii \
sun/tools/jrunscript
svc_tools = \
com/sun/tools/attach \
com/sun/tracing \
sun/tools \
-sun/tools/java \
-sun/tools/native2ascii \
-sun/tools/jrunscript \
sun/jvmstat \
demo/jvmti
jdk_tools = \
:core_tools \
:svc_tools
#
# Catch-all for other areas with a small number of tests
#
jdk_other = \
java/sql \
javax/sql \
javax/naming \
javax/script \
javax/smartcardio \
javax/xml \
-javax/xml/crypto \
jdk/asm \
jdk/lambda \
com/sun/jndi \
com/sun/corba \
lib/testlibrary \
demo/zipfs \
sample
#
# SCTP is its own group as it is highly sensitive to kernel/network config
#
jdk_sctp = \
com/sun/nio/sctp
#
# core group to run all core area tests
#
jdk_core = \
:jdk_lang \
:jdk_util \
:jdk_math \
:jdk_io \
:jdk_nio \
:jdk_net \
:jdk_rmi \
:jdk_time \
:jdk_security \
:jdk_text \
:core_tools \
:jdk_other
#
# svc group to run all serviceability area tests
#
jdk_svc = \
:jdk_management \
:jdk_instrument \
:jdk_jmx \
:jdk_jdi \
:svc_tools
#############################
#
# Client area groups
#
jdk_awt = \
java/awt \
com/sun/awt \
com/apple/eawt \
sun/awt
jdk_2d = \
javax/print \
sun/pisces \
sun/java2d
jdk_beans = \
java/beans
jdk_swing = \
javax/accessibility \
javax/swing \
com/sun/java/swing
jdk_sound = \
javax/sound
jdk_imageio = \
javax/imageio
jdk_desktop = \
:jdk_awt \
:jdk_2d \
:jdk_beans \
:jdk_swing \
:jdk_sound \
:jdk_imageio
test/java/io/BufferedInputStream/LargeCopyWithMark.java
0 → 100644
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 7129312
* @summary BufferedInputStream calculates negative array size with large
* streams and mark
* @library /lib/testlibrary
* @run main/othervm LargeCopyWithMark
*/
import
java.io.BufferedInputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
static
jdk
.
testlibrary
.
ProcessTools
.*;
public
class
LargeCopyWithMark
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
if
(!
System
.
getProperty
(
"os.arch"
).
contains
(
"64"
))
{
System
.
out
.
println
(
"Test runs on 64 bit platforms"
);
return
;
}
ProcessBuilder
pb
=
createJavaProcessBuilder
(
"-Xmx4G"
,
"-ea:LargeCopyWithMark$Child"
,
"LargeCopyWithMark$Child"
);
int
res
=
pb
.
inheritIO
().
start
().
waitFor
();
if
(
res
!=
0
)
{
throw
new
AssertionError
(
"Test failed: exit code = "
+
res
);
}
}
public
static
class
Child
{
static
final
int
BUFF_SIZE
=
8192
;
static
final
int
BIS_BUFF_SIZE
=
Integer
.
MAX_VALUE
/
2
+
100
;
static
final
long
BYTES_TO_COPY
=
2L
*
Integer
.
MAX_VALUE
;
static
{
assert
BIS_BUFF_SIZE
*
2
<
0
:
"doubling must overflow"
;
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
byte
[]
buff
=
new
byte
[
BUFF_SIZE
];
try
(
InputStream
myis
=
new
MyInputStream
(
BYTES_TO_COPY
);
InputStream
bis
=
new
BufferedInputStream
(
myis
,
BIS_BUFF_SIZE
);
OutputStream
myos
=
new
MyOutputStream
())
{
// will require a buffer bigger than BIS_BUFF_SIZE
bis
.
mark
(
BIS_BUFF_SIZE
+
100
);
for
(;;)
{
int
count
=
bis
.
read
(
buff
,
0
,
BUFF_SIZE
);
if
(
count
==
-
1
)
break
;
myos
.
write
(
buff
,
0
,
count
);
}
}
catch
(
java
.
lang
.
NegativeArraySizeException
e
)
{
e
.
printStackTrace
();
System
.
exit
(
11
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
}
class
MyInputStream
extends
InputStream
{
private
long
bytesLeft
;
public
MyInputStream
(
long
bytesLeft
)
{
this
.
bytesLeft
=
bytesLeft
;
}
@Override
public
int
read
()
throws
IOException
{
return
0
;
}
@Override
public
int
read
(
byte
[]
b
)
throws
IOException
{
return
read
(
b
,
0
,
b
.
length
);
}
@Override
public
int
read
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{
if
(
bytesLeft
<=
0
)
return
-
1
;
long
result
=
Math
.
min
(
bytesLeft
,
(
long
)
len
);
bytesLeft
-=
result
;
return
(
int
)
result
;
}
@Override
public
int
available
()
throws
IOException
{
return
(
bytesLeft
>
0
)
?
1
:
0
;
}
}
class
MyOutputStream
extends
OutputStream
{
@Override
public
void
write
(
int
b
)
throws
IOException
{}
@Override
public
void
write
(
byte
[]
b
)
throws
IOException
{}
@Override
public
void
write
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{}
}
test/java/io/File/MaxPathLength.java
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2002, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -27,6 +27,7 @@
*/
import
java.io.*
;
import
java.nio.file.Files
;
public
class
MaxPathLength
{
private
static
String
sep
=
File
.
separator
;
...
...
@@ -87,10 +88,8 @@ public class MaxPathLength {
System
.
err
.
println
(
"Warning: Test directory structure exists already!"
);
return
;
}
boolean
couldMakeTestDirectory
=
dirFile
.
mkdirs
();
if
(!
couldMakeTestDirectory
)
{
throw
new
RuntimeException
(
"Could not create test directory structure"
);
}
Files
.
createDirectories
(
dirFile
.
toPath
());
try
{
if
(
tryAbsolute
)
dirFile
=
new
File
(
dirFile
.
getCanonicalPath
());
...
...
test/java/io/pathNames/General.java
浏览文件 @
f9ad02d9
...
...
@@ -28,6 +28,7 @@
import
java.io.*
;
import
java.util.*
;
import
java.nio.file.*
;
public
class
General
{
...
...
@@ -57,7 +58,7 @@ public class General {
for
(
int
i
=
0
;
i
<
dl
.
length
;
i
++)
{
File
f
=
new
File
(
subdir
,
dl
[
i
]);
File
df
=
new
File
(
dir
,
f
.
getPath
());
if
(
df
.
exists
()
&&
df
.
isFile
(
))
{
if
(
Files
.
isRegularFile
(
df
.
toPath
(),
LinkOption
.
NOFOLLOW_LINKS
))
{
return
f
.
getPath
();
}
}
...
...
@@ -65,7 +66,7 @@ public class General {
File
f
=
(
subdir
.
length
()
==
0
)
?
new
File
(
dl
[
i
])
:
new
File
(
subdir
,
dl
[
i
]);
File
df
=
new
File
(
dir
,
f
.
getPath
());
if
(
df
.
exists
()
&&
df
.
isDirectory
(
))
{
if
(
Files
.
isDirectory
(
df
.
toPath
(),
LinkOption
.
NOFOLLOW_LINKS
))
{
String
[]
dl2
=
df
.
list
();
if
(
dl2
!=
null
)
{
String
ff
=
findSomeFile
(
dir
,
f
.
getPath
(),
dl2
);
...
...
@@ -90,7 +91,7 @@ public class General {
}
for
(
int
i
=
0
;
i
<
dl
.
length
;
i
++)
{
File
f
=
new
File
(
dir
,
dl
[
i
]);
if
(
f
.
isFile
(
))
{
if
(
Files
.
isRegularFile
(
f
.
toPath
(),
LinkOption
.
NOFOLLOW_LINKS
))
{
return
dl
[
i
];
}
}
...
...
@@ -127,7 +128,7 @@ public class General {
}
for
(
int
i
=
0
;
i
<
dl
.
length
;
i
++)
{
File
f
=
new
File
(
d
,
dl
[
i
]);
if
(
f
.
isDirectory
(
))
{
if
(
Files
.
isDirectory
(
f
.
toPath
(),
LinkOption
.
NOFOLLOW_LINKS
))
{
String
[]
dl2
=
f
.
list
();
if
(
dl2
==
null
||
dl2
.
length
>=
250
)
{
/* Heuristic to avoid scanning huge directories */
...
...
@@ -314,7 +315,7 @@ public class General {
/* Normal name */
if
(
f
.
exists
())
{
if
(
f
.
isDirectory
(
)
&&
f
.
list
()
!=
null
)
{
if
(
Files
.
isDirectory
(
f
.
toPath
(),
LinkOption
.
NOFOLLOW_LINKS
)
&&
f
.
list
()
!=
null
)
{
if
((
n
=
findSomeFile
(
ans
,
create
))
!=
null
)
checkSlashes
(
d
,
create
,
ans
+
n
,
ask
+
n
);
if
((
n
=
findSomeDir
(
ans
,
create
))
!=
null
)
...
...
test/java/lang/SecurityManager/CheckPackageAccess.java
浏览文件 @
f9ad02d9
...
...
@@ -23,7 +23,7 @@
/*
* @test
* @bug 6741606 7146431 8000450
* @bug 6741606 7146431 8000450
8019830
* @summary Make sure all restricted packages listed in the package.access
* property in the java.security file are blocked
* @run main/othervm CheckPackageAccess
...
...
@@ -54,6 +54,7 @@ public class CheckPackageAccess {
"com.sun.imageio."
,
"com.sun.istack.internal."
,
"com.sun.jmx."
,
"com.sun.media.sound."
,
"com.sun.proxy."
,
"com.sun.org.apache.bcel.internal."
,
"com.sun.org.apache.regexp.internal."
,
...
...
test/java/lang/annotation/AnnotationType/AnnotationTypeDeadlockTest.java
浏览文件 @
f9ad02d9
...
...
@@ -28,6 +28,9 @@
*/
import
java.lang.annotation.Retention
;
import
java.lang.management.ManagementFactory
;
import
java.lang.management.ThreadInfo
;
import
java.lang.management.ThreadMXBean
;
import
java.util.concurrent.CountDownLatch
;
import
java.util.concurrent.atomic.AtomicInteger
;
...
...
@@ -66,17 +69,6 @@ public class AnnotationTypeDeadlockTest {
}
}
static
void
dumpState
(
Task
task
)
{
System
.
err
.
println
(
"Task["
+
task
.
getName
()
+
"].state: "
+
task
.
getState
()
+
" ..."
);
for
(
StackTraceElement
ste
:
task
.
getStackTrace
())
{
System
.
err
.
println
(
"\tat "
+
ste
);
}
System
.
err
.
println
();
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
CountDownLatch
prepareLatch
=
new
CountDownLatch
(
2
);
AtomicInteger
goLatch
=
new
AtomicInteger
(
1
);
...
...
@@ -88,18 +80,22 @@ public class AnnotationTypeDeadlockTest {
prepareLatch
.
await
();
// let them go
goLatch
.
set
(
0
);
// attempt to join them
taskA
.
join
(
5000L
);
taskB
.
join
(
5000L
);
if
(
taskA
.
isAlive
()
||
taskB
.
isAlive
())
{
dumpState
(
taskA
);
dumpState
(
taskB
);
throw
new
IllegalStateException
(
taskA
.
getState
()
==
Thread
.
State
.
BLOCKED
&&
taskB
.
getState
()
==
Thread
.
State
.
BLOCKED
?
"deadlock detected"
:
"unexpected condition"
);
// obtain ThreadMXBean
ThreadMXBean
threadBean
=
ManagementFactory
.
getThreadMXBean
();
// wait for threads to finish or dead-lock
while
(
taskA
.
isAlive
()
||
taskB
.
isAlive
())
{
// attempt to join threads
taskA
.
join
(
500L
);
taskB
.
join
(
500L
);
// detect dead-lock
long
[]
deadlockedIds
=
threadBean
.
findMonitorDeadlockedThreads
();
if
(
deadlockedIds
!=
null
&&
deadlockedIds
.
length
>
0
)
{
StringBuilder
sb
=
new
StringBuilder
(
"deadlock detected:\n\n"
);
for
(
ThreadInfo
ti
:
threadBean
.
getThreadInfo
(
deadlockedIds
,
Integer
.
MAX_VALUE
))
{
sb
.
append
(
ti
);
}
throw
new
IllegalStateException
(
sb
.
toString
());
}
}
}
}
test/java/lang/annotation/TypeAnnotationReflection.java
浏览文件 @
f9ad02d9
...
...
@@ -23,7 +23,7 @@
/*
* @test
* @bug 8004698 8007073
* @bug 8004698 8007073
8022343
* @summary Unit test for type annotations
*/
...
...
@@ -58,7 +58,7 @@ public class TypeAnnotationReflection {
}
private
static
void
testSuper
()
throws
Exception
{
check
(
Object
.
class
.
getAnnotatedSuperclass
()
.
getAnnotations
().
length
==
0
);
check
(
Object
.
class
.
getAnnotatedSuperclass
()
==
null
);
check
(
Class
.
class
.
getAnnotatedSuperclass
().
getAnnotations
().
length
==
0
);
AnnotatedType
a
;
...
...
src/share/classes/sun/misc/Sort
.java
→
test/java/lang/annotation/typeAnnotations/GetAnnotatedSuperclass
.java
浏览文件 @
f9ad02d9
/*
* Copyright (c)
1996
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c)
2013
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
...
...
@@ -23,52 +21,36 @@
* questions.
*/
/**
* Sort: a class that uses the quicksort algorithm to sort an
* array of objects.
*
* @author Sunita Mani
*/
package
sun.misc
;
public
class
Sort
{
private
static
void
swap
(
Object
arr
[],
int
i
,
int
j
)
{
Object
tmp
;
tmp
=
arr
[
i
];
arr
[
i
]
=
arr
[
j
];
arr
[
j
]
=
tmp
;
}
/**
* quicksort the array of objects.
*
* @param arr[] - an array of objects
* @param left - the start index - from where to begin sorting
* @param right - the last index.
* @param comp - an object that implemnts the Compare interface to resolve thecomparison.
/*
* @test
* @bug 8022343
* @summary make sure Class.getAnnotatedSuperclass() returns null when specified to do so
*/
public
static
void
quicksort
(
Object
arr
[],
int
left
,
int
right
,
Compare
comp
)
{
int
i
,
last
;
if
(
left
>=
right
)
{
/* do nothing if array contains fewer than two */
return
;
/* two elements */
public
class
GetAnnotatedSuperclass
{
private
static
final
Class
<?>[]
testData
=
{
Object
.
class
,
If
.
class
,
Object
[].
class
,
void
.
class
,
int
.
class
,
};
public
static
void
main
(
String
[]
args
)
throws
Exception
{
int
failed
=
0
;
for
(
Class
<?>
toTest
:
testData
)
{
Object
res
=
toTest
.
getAnnotatedSuperclass
();
if
(
res
!=
null
)
{
failed
++;
System
.
out
.
println
(
toTest
+
".getAnnotatedSuperclass() returns: "
+
res
+
", should be null"
);
}
swap
(
arr
,
left
,
(
left
+
right
)
/
2
);
last
=
left
;
for
(
i
=
left
+
1
;
i
<=
right
;
i
++)
{
if
(
comp
.
doCompare
(
arr
[
i
],
arr
[
left
])
<
0
)
{
swap
(
arr
,
++
last
,
i
);
}
}
swap
(
arr
,
left
,
last
);
quicksort
(
arr
,
left
,
last
-
1
,
comp
);
quicksort
(
arr
,
last
+
1
,
right
,
comp
);
}
public
static
void
quicksort
(
Object
arr
[],
Compare
comp
)
{
quicksort
(
arr
,
0
,
arr
.
length
-
1
,
comp
);
if
(
failed
!=
0
)
throw
new
RuntimeException
(
"Test failed, check log for details"
);
}
interface
If
{}
}
test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java
浏览文件 @
f9ad02d9
...
...
@@ -33,10 +33,10 @@
* @author Mandy Chung
*
* @build ResetPeakMemoryUsage MemoryUtil
* @run main/othervm -XX:+
UseSerialGC
-XX:MarkSweepAlwaysCompactCount=1 -Xmn8m ResetPeakMemoryUsage
* @run main/othervm -XX:+
UseConcMarkSweepGC
-Xmn8m ResetPeakMemoryUsage
* @run main/othervm -XX:+
UseParallelGC
-Xmn8m ResetPeakMemoryUsage
* @run main/othervm -XX:+
UseG1GC
-Xmn8m -XX:G1HeapRegionSize=1m ResetPeakMemoryUsage
* @run main/othervm -XX:+
PrintGCDetails -XX:+UseSerialGC -Xms256m
-XX:MarkSweepAlwaysCompactCount=1 -Xmn8m ResetPeakMemoryUsage
* @run main/othervm -XX:+
PrintGCDetails -XX:+UseConcMarkSweepGC -Xms256m
-Xmn8m ResetPeakMemoryUsage
* @run main/othervm -XX:+
PrintGCDetails -XX:+UseParallelGC -Xms256m
-Xmn8m ResetPeakMemoryUsage
* @run main/othervm -XX:+
PrintGCDetails -XX:+UseG1GC -Xms256m
-Xmn8m -XX:G1HeapRegionSize=1m ResetPeakMemoryUsage
*/
import
java.lang.management.*
;
...
...
test/java/math/BigDecimal/IntegralDivisionTests.java
浏览文件 @
f9ad02d9
...
...
@@ -22,7 +22,7 @@
*/
/*
* @test
* @bug 4904082 4917089 6337226
* @bug 4904082 4917089 6337226
6378503
* @summary Tests that integral division and related methods return the proper result and scale.
* @author Joseph D. Darcy
*/
...
...
@@ -47,6 +47,9 @@ public class IntegralDivisionTests {
{
new
BigDecimal
(
"400e1"
),
new
BigDecimal
(
"5"
),
new
BigDecimal
(
"80e1"
)},
{
new
BigDecimal
(
"400e1"
),
new
BigDecimal
(
"4.999999999"
),
new
BigDecimal
(
"8e2"
)},
{
new
BigDecimal
(
"40e2"
),
new
BigDecimal
(
"5"
),
new
BigDecimal
(
"8e2"
)},
{
BigDecimal
.
valueOf
(
1
,
Integer
.
MIN_VALUE
),
BigDecimal
.
valueOf
(
1
,
-(
Integer
.
MAX_VALUE
&
0x7fffff00
)),
BigDecimal
.
valueOf
(
1
,
-
256
)},
};
for
(
BigDecimal
[]
testCase:
moreTestCases
)
{
...
...
test/java/nio/file/WatchService/SensitivityModifier.java
浏览文件 @
f9ad02d9
...
...
@@ -54,7 +54,7 @@ public class SensitivityModifier {
@SuppressWarnings
(
"unchecked"
)
static
void
doTest
(
Path
top
)
throws
Exception
{
FileSystem
fs
=
top
.
getFileSystem
();
WatchService
watcher
=
fs
.
newWatchService
();
try
(
WatchService
watcher
=
fs
.
newWatchService
())
{
// create directories and files
int
nDirs
=
5
+
rand
.
nextInt
(
20
);
...
...
@@ -84,30 +84,36 @@ public class SensitivityModifier {
try
(
OutputStream
out
=
Files
.
newOutputStream
(
file
))
{
out
.
write
(
new
byte
[
100
]);
}
System
.
out
.
println
(
"Waiting for event..."
);
System
.
out
.
println
(
"Waiting for event(s)..."
);
boolean
eventReceived
=
false
;
WatchKey
key
=
watcher
.
take
();
WatchEvent
<?>
event
=
key
.
pollEvents
().
iterator
().
next
();
do
{
for
(
WatchEvent
<?>
event:
key
.
pollEvents
())
{
if
(
event
.
kind
()
!=
ENTRY_MODIFY
)
throw
new
RuntimeException
(
"Unexpected event: "
+
event
);
Path
name
=
((
WatchEvent
<
Path
>)
event
).
context
();
if
(!
name
.
equals
(
file
.
getFileName
()))
throw
new
RuntimeException
(
"Unexpected context: "
+
name
);
System
.
out
.
println
(
"Event OK"
);
// drain events (to avoid interference)
do
{
key
.
pollEvents
();
if
(
name
.
equals
(
file
.
getFileName
()))
{
eventReceived
=
true
;
break
;
}
}
key
.
reset
();
key
=
watcher
.
poll
(
1
,
TimeUnit
.
SECONDS
);
}
while
(
key
!=
null
);
}
while
(
key
!=
null
&&
!
eventReceived
);
// we should have received at least one ENTRY_MODIFY event
if
(
eventReceived
)
{
System
.
out
.
println
(
"Event OK"
);
}
else
{
throw
new
RuntimeException
(
"No ENTRY_MODIFY event received for "
+
file
);
}
// re-register the directories to force changing their sensitivity
// level
register
(
dirs
,
watcher
);
}
// done
watcher
.
close
();
}
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
...
...
test/java/util/Arrays/TimSortStackSize.java
0 → 100644
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8011944
* @summary Test TimSort stack size
*/
import
java.util.Arrays
;
import
java.util.ArrayDeque
;
public
class
TimSortStackSize
{
public
static
void
main
(
String
[]
args
)
{
testComparableTimSort
();
testTimSort
();
}
static
void
testComparableTimSort
()
{
System
.
out
.
printf
(
"testComparableTimSort()%n"
);
Arrays
.
sort
(
genData
());
}
static
void
testTimSort
()
{
System
.
out
.
printf
(
"testTimSort()%n"
);
Arrays
.
sort
(
genData
(),
Integer:
:
compare
);
}
private
static
final
int
MIN
=
16
;
private
static
final
int
BOUND1
=
2
*
MIN
+
1
;
private
static
final
int
BOUND2
=
BOUND1
+
MIN
+
2
;
private
static
final
int
BOUND3
=
BOUND1
+
1
+
BOUND2
;
private
static
final
int
BOUND4
=
BOUND2
+
1
+
BOUND3
;
private
static
final
int
BOUND5
=
BOUND3
+
1
+
BOUND4
;
static
int
build
(
int
size
,
int
B
,
ArrayDeque
<
Integer
>
chunks
)
{
chunks
.
addFirst
(
B
);
if
(
size
<
BOUND1
)
{
chunks
.
addFirst
(
size
);
return
size
;
}
int
asize
=
(
size
+
2
)
/
2
;
if
(
size
>=
BOUND2
&&
asize
<
BOUND1
)
{
asize
=
BOUND1
;
}
else
if
(
size
>=
BOUND3
&&
asize
<
BOUND2
)
{
asize
=
BOUND2
;
}
else
if
(
size
>=
BOUND4
&&
asize
<
BOUND3
)
{
asize
=
BOUND3
;
}
else
if
(
size
>=
BOUND5
&&
asize
<
BOUND4
)
{
asize
=
BOUND4
;
}
if
(
size
-
asize
>=
B
)
{
throw
new
AssertionError
(
" "
+
size
+
" , "
+
asize
+
" , "
+
B
);
}
return
build
(
asize
,
size
-
asize
,
chunks
);
}
static
Integer
[]
genData
()
{
ArrayDeque
<
Integer
>
chunks
=
new
ArrayDeque
<
Integer
>();
chunks
.
addFirst
(
MIN
);
int
B
=
MIN
+
4
;
int
A
=
B
+
MIN
+
1
;
for
(
int
i
=
0
;
i
<
8
;
i
++)
{
int
eps
=
build
(
A
,
B
,
chunks
);
B
=
B
+
A
+
1
;
A
=
B
+
eps
+
1
;
}
chunks
.
addFirst
(
B
);
chunks
.
addFirst
(
A
);
int
total
=
0
;
for
(
Integer
len
:
chunks
)
{
total
+=
len
;
}
int
pow
=
MIN
;
while
(
pow
<
total
)
{
pow
+=
pow
;
}
chunks
.
addLast
(
pow
-
total
);
System
.
out
.
println
(
" Total: "
+
total
);
Integer
[]
array
=
new
Integer
[
pow
];
int
off
=
0
;
int
pos
=
0
;
for
(
Integer
len
:
chunks
)
{
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
array
[
pos
++]
=
Integer
.
valueOf
(
i
==
0
?
0
:
1
);
}
off
++;
}
return
array
;
}
}
test/java/util/Collections/Wrappers.java
0 → 100644
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @run testng Wrappers
* @summary Ensure Collections wrapping classes provide non-default implementations
*/
import
java.lang.reflect.Method
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Objects
;
import
java.util.TreeMap
;
import
java.util.TreeSet
;
import
org.testng.annotations.Test
;
import
org.testng.annotations.DataProvider
;
import
static
org
.
testng
.
Assert
.
assertFalse
;
@Test
(
groups
=
"unit"
)
public
class
Wrappers
{
static
Object
[][]
collections
;
@DataProvider
(
name
=
"collections"
)
public
static
Object
[][]
collectionCases
()
{
if
(
collections
!=
null
)
{
return
collections
;
}
List
<
Object
[]>
cases
=
new
ArrayList
<>();
LinkedList
<
Integer
>
seedList
=
new
LinkedList
<>();
ArrayList
<
Integer
>
seedRandomAccess
=
new
ArrayList
<>();
TreeSet
<
Integer
>
seedSet
=
new
TreeSet
<>();
TreeMap
<
Integer
,
Integer
>
seedMap
=
new
TreeMap
<>();
for
(
int
i
=
1
;
i
<=
10
;
i
++)
{
seedList
.
add
(
i
);
seedRandomAccess
.
add
(
i
);
seedSet
.
add
(
i
);
seedMap
.
put
(
i
,
i
);
}
cases
.
add
(
new
Object
[]
{
Collections
.
unmodifiableCollection
(
seedList
)
});
cases
.
add
(
new
Object
[]
{
Collections
.
unmodifiableList
(
seedList
)
});
cases
.
add
(
new
Object
[]
{
Collections
.
unmodifiableList
(
seedRandomAccess
)
});
cases
.
add
(
new
Object
[]
{
Collections
.
unmodifiableSet
(
seedSet
)
});
cases
.
add
(
new
Object
[]
{
Collections
.
unmodifiableSortedSet
(
seedSet
)
});
cases
.
add
(
new
Object
[]
{
Collections
.
unmodifiableNavigableSet
(
seedSet
)
});
// As sets from map also need to be unmodifiable, thus a wrapping
// layer exist and should not have default methods
cases
.
add
(
new
Object
[]
{
Collections
.
unmodifiableMap
(
seedMap
).
entrySet
()
});
cases
.
add
(
new
Object
[]
{
Collections
.
unmodifiableMap
(
seedMap
).
keySet
()
});
cases
.
add
(
new
Object
[]
{
Collections
.
unmodifiableMap
(
seedMap
).
values
()
});
cases
.
add
(
new
Object
[]
{
Collections
.
unmodifiableSortedMap
(
seedMap
).
entrySet
()
});
cases
.
add
(
new
Object
[]
{
Collections
.
unmodifiableSortedMap
(
seedMap
).
keySet
()
});
cases
.
add
(
new
Object
[]
{
Collections
.
unmodifiableSortedMap
(
seedMap
).
values
()
});
cases
.
add
(
new
Object
[]
{
Collections
.
unmodifiableNavigableMap
(
seedMap
).
entrySet
()
});
cases
.
add
(
new
Object
[]
{
Collections
.
unmodifiableNavigableMap
(
seedMap
).
keySet
()
});
cases
.
add
(
new
Object
[]
{
Collections
.
unmodifiableNavigableMap
(
seedMap
).
values
()
});
// Synchronized
cases
.
add
(
new
Object
[]
{
Collections
.
synchronizedCollection
(
seedList
)
});
cases
.
add
(
new
Object
[]
{
Collections
.
synchronizedList
(
seedList
)
});
cases
.
add
(
new
Object
[]
{
Collections
.
synchronizedList
(
seedRandomAccess
)
});
cases
.
add
(
new
Object
[]
{
Collections
.
synchronizedSet
(
seedSet
)
});
cases
.
add
(
new
Object
[]
{
Collections
.
synchronizedSortedSet
(
seedSet
)
});
cases
.
add
(
new
Object
[]
{
Collections
.
synchronizedNavigableSet
(
seedSet
)
});
// As sets from map also need to be synchronized on the map, thus a
// wrapping layer exist and should not have default methods
cases
.
add
(
new
Object
[]
{
Collections
.
synchronizedMap
(
seedMap
).
entrySet
()
});
cases
.
add
(
new
Object
[]
{
Collections
.
synchronizedMap
(
seedMap
).
keySet
()
});
cases
.
add
(
new
Object
[]
{
Collections
.
synchronizedMap
(
seedMap
).
values
()
});
cases
.
add
(
new
Object
[]
{
Collections
.
synchronizedSortedMap
(
seedMap
).
entrySet
()
});
cases
.
add
(
new
Object
[]
{
Collections
.
synchronizedSortedMap
(
seedMap
).
keySet
()
});
cases
.
add
(
new
Object
[]
{
Collections
.
synchronizedSortedMap
(
seedMap
).
values
()
});
cases
.
add
(
new
Object
[]
{
Collections
.
synchronizedNavigableMap
(
seedMap
).
entrySet
()
});
cases
.
add
(
new
Object
[]
{
Collections
.
synchronizedNavigableMap
(
seedMap
).
keySet
()
});
cases
.
add
(
new
Object
[]
{
Collections
.
synchronizedNavigableMap
(
seedMap
).
values
()
});
// Checked
cases
.
add
(
new
Object
[]
{
Collections
.
checkedCollection
(
seedList
,
Integer
.
class
)
});
cases
.
add
(
new
Object
[]
{
Collections
.
checkedList
(
seedList
,
Integer
.
class
)
});
cases
.
add
(
new
Object
[]
{
Collections
.
checkedList
(
seedRandomAccess
,
Integer
.
class
)
});
cases
.
add
(
new
Object
[]
{
Collections
.
checkedSet
(
seedSet
,
Integer
.
class
)
});
cases
.
add
(
new
Object
[]
{
Collections
.
checkedSortedSet
(
seedSet
,
Integer
.
class
)
});
cases
.
add
(
new
Object
[]
{
Collections
.
checkedNavigableSet
(
seedSet
,
Integer
.
class
)
});
cases
.
add
(
new
Object
[]
{
Collections
.
checkedQueue
(
seedList
,
Integer
.
class
)
});
// asLifoQueue is another wrapper
cases
.
add
(
new
Object
[]
{
Collections
.
asLifoQueue
(
seedList
)
});
collections
=
cases
.
toArray
(
new
Object
[
0
][]);
return
collections
;
}
static
Method
[]
defaultMethods
;
static
{
List
<
Method
>
list
=
new
ArrayList
<>();
Method
[]
methods
=
Collection
.
class
.
getMethods
();
for
(
Method
m:
methods
)
{
if
(
m
.
isDefault
())
{
list
.
add
(
m
);
}
}
defaultMethods
=
list
.
toArray
(
new
Method
[
0
]);
}
@Test
(
dataProvider
=
"collections"
)
public
static
void
testAllDefaultMethodsOverridden
(
Collection
c
)
throws
NoSuchMethodException
{
Class
cls
=
c
.
getClass
();
for
(
Method
m:
defaultMethods
)
{
Method
m2
=
cls
.
getMethod
(
m
.
getName
(),
m
.
getParameterTypes
());
// default had been override
assertFalse
(
m2
.
isDefault
(),
cls
.
getCanonicalName
());
}
}
}
test/java/util/Comparator/BasicTest.java
浏览文件 @
f9ad02d9
...
...
@@ -90,7 +90,7 @@ public class BasicTest {
Thing
[]
things
=
new
Thing
[
intValues
.
length
];
for
(
int
i
=
0
;
i
<
intValues
.
length
;
i
++)
things
[
i
]
=
new
Thing
(
intValues
[
i
],
0L
,
0.0
,
null
);
Comparator
<
Thing
>
comp
=
Comparator
.
comparing
(
new
ToIntFunction
<
Thing
>()
{
Comparator
<
Thing
>
comp
=
Comparator
.
comparing
Int
(
new
ToIntFunction
<
Thing
>()
{
@Override
public
int
applyAsInt
(
Thing
thing
)
{
return
thing
.
getIntField
();
...
...
@@ -104,7 +104,7 @@ public class BasicTest {
Thing
[]
things
=
new
Thing
[
longValues
.
length
];
for
(
int
i
=
0
;
i
<
longValues
.
length
;
i
++)
things
[
i
]
=
new
Thing
(
0
,
longValues
[
i
],
0.0
,
null
);
Comparator
<
Thing
>
comp
=
Comparator
.
comparing
(
new
ToLongFunction
<
Thing
>()
{
Comparator
<
Thing
>
comp
=
Comparator
.
comparing
Long
(
new
ToLongFunction
<
Thing
>()
{
@Override
public
long
applyAsLong
(
Thing
thing
)
{
return
thing
.
getLongField
();
...
...
@@ -118,7 +118,7 @@ public class BasicTest {
Thing
[]
things
=
new
Thing
[
doubleValues
.
length
];
for
(
int
i
=
0
;
i
<
doubleValues
.
length
;
i
++)
things
[
i
]
=
new
Thing
(
0
,
0L
,
doubleValues
[
i
],
null
);
Comparator
<
Thing
>
comp
=
Comparator
.
comparing
(
new
ToDoubleFunction
<
Thing
>()
{
Comparator
<
Thing
>
comp
=
Comparator
.
comparing
Double
(
new
ToDoubleFunction
<
Thing
>()
{
@Override
public
double
applyAsDouble
(
Thing
thing
)
{
return
thing
.
getDoubleField
();
...
...
@@ -211,8 +211,8 @@ public class BasicTest {
};
public
void
testComparatorDefaultMethods
()
{
Comparator
<
People
>
cmp
=
Comparator
.
comparing
(
(
Function
<
People
,
String
>)
People:
:
getFirstName
);
Comparator
<
People
>
cmp2
=
Comparator
.
comparing
(
(
Function
<
People
,
String
>)
People:
:
getLastName
);
Comparator
<
People
>
cmp
=
Comparator
.
comparing
(
People:
:
getFirstName
);
Comparator
<
People
>
cmp2
=
Comparator
.
comparing
(
People:
:
getLastName
);
// reverseOrder
assertComparison
(
cmp
.
reversed
(),
people
[
1
],
people
[
0
]);
// thenComparing(Comparator)
...
...
@@ -222,20 +222,20 @@ public class BasicTest {
assertComparison
(
cmp
.
thenComparing
(
People:
:
getLastName
),
people
[
0
],
people
[
1
]);
assertComparison
(
cmp
.
thenComparing
(
People:
:
getLastName
),
people
[
4
],
people
[
0
]);
// thenComparing(ToIntFunction)
assertComparison
(
cmp
.
thenComparing
(
People:
:
getAge
),
people
[
0
],
people
[
1
]);
assertComparison
(
cmp
.
thenComparing
(
People:
:
getAge
),
people
[
1
],
people
[
5
]);
assertComparison
(
cmp
.
thenComparing
Int
(
People:
:
getAge
),
people
[
0
],
people
[
1
]);
assertComparison
(
cmp
.
thenComparing
Int
(
People:
:
getAge
),
people
[
1
],
people
[
5
]);
// thenComparing(ToLongFunction)
assertComparison
(
cmp
.
thenComparing
(
People:
:
getAgeAsLong
),
people
[
0
],
people
[
1
]);
assertComparison
(
cmp
.
thenComparing
(
People:
:
getAgeAsLong
),
people
[
1
],
people
[
5
]);
assertComparison
(
cmp
.
thenComparing
Long
(
People:
:
getAgeAsLong
),
people
[
0
],
people
[
1
]);
assertComparison
(
cmp
.
thenComparing
Long
(
People:
:
getAgeAsLong
),
people
[
1
],
people
[
5
]);
// thenComparing(ToDoubleFunction)
assertComparison
(
cmp
.
thenComparing
(
People:
:
getAgeAsDouble
),
people
[
0
],
people
[
1
]);
assertComparison
(
cmp
.
thenComparing
(
People:
:
getAgeAsDouble
),
people
[
1
],
people
[
5
]);
assertComparison
(
cmp
.
thenComparing
Double
(
People:
:
getAgeAsDouble
),
people
[
0
],
people
[
1
]);
assertComparison
(
cmp
.
thenComparing
Double
(
People:
:
getAgeAsDouble
),
people
[
1
],
people
[
5
]);
}
public
void
testNullsFirst
()
{
Comparator
<
String
>
strcmp
=
Comparator
.
nullsFirst
(
Comparator
.
naturalOrder
());
Comparator
<
People
>
cmp
=
Comparator
.
<
People
,
String
>
comparing
(
People:
:
getLastName
,
strcmp
)
Comparator
<
People
>
cmp
=
Comparator
.
comparing
(
People:
:
getLastName
,
strcmp
)
.
thenComparing
(
People:
:
getFirstName
,
strcmp
);
// Mary.null vs Mary.Cook - solve by last name
assertComparison
(
cmp
,
people
[
6
],
people
[
5
]);
...
...
@@ -243,7 +243,7 @@ public class BasicTest {
assertComparison
(
cmp
,
people
[
7
],
people
[
6
]);
// More than one thenComparing
strcmp
=
Comparator
.
nullsFirst
(
Comparator
.
comparing
((
ToIntFunction
<
String
>)
String:
:
length
)
strcmp
=
Comparator
.
nullsFirst
(
Comparator
.
comparing
Int
(
String:
:
length
)
.
thenComparing
(
String
.
CASE_INSENSITIVE_ORDER
));
assertComparison
(
strcmp
,
null
,
"abc"
);
assertComparison
(
strcmp
,
"ab"
,
"abc"
);
...
...
@@ -273,7 +273,7 @@ public class BasicTest {
public
void
testNullsLast
()
{
Comparator
<
String
>
strcmp
=
Comparator
.
nullsLast
(
Comparator
.
naturalOrder
());
Comparator
<
People
>
cmp
=
Comparator
.
<
People
,
String
>
comparing
(
People:
:
getLastName
,
strcmp
)
Comparator
<
People
>
cmp
=
Comparator
.
comparing
(
People:
:
getLastName
,
strcmp
)
.
thenComparing
(
People:
:
getFirstName
,
strcmp
);
// Mary.null vs Mary.Cook - solve by last name
assertComparison
(
cmp
,
people
[
5
],
people
[
6
]);
...
...
@@ -281,7 +281,7 @@ public class BasicTest {
assertComparison
(
cmp
,
people
[
7
],
people
[
6
]);
// More than one thenComparing
strcmp
=
Comparator
.
nullsLast
(
Comparator
.
comparing
((
ToIntFunction
<
String
>)
String:
:
length
)
strcmp
=
Comparator
.
nullsLast
(
Comparator
.
comparing
Int
(
String:
:
length
)
.
thenComparing
(
String
.
CASE_INSENSITIVE_ORDER
));
assertComparison
(
strcmp
,
"abc"
,
null
);
assertComparison
(
strcmp
,
"ab"
,
"abc"
);
...
...
@@ -341,28 +341,28 @@ public class BasicTest {
}
catch
(
NullPointerException
npe
)
{}
try
{
Comparator
<
People
>
cmp
=
Comparator
.
comparing
(
(
Function
<
People
,
String
>)
null
,
Comparator
.<
String
>
naturalOrder
());
Comparator
<
People
>
cmp
=
Comparator
.
comparing
(
null
,
Comparator
.<
String
>
naturalOrder
());
fail
(
"comparing(null, cmp) should throw NPE"
);
}
catch
(
NullPointerException
npe
)
{}
try
{
Comparator
<
People
>
cmp
=
Comparator
.
comparing
(
(
Function
<
People
,
String
>)
People:
:
getFirstName
,
null
);
Comparator
<
People
>
cmp
=
Comparator
.
comparing
(
People:
:
getFirstName
,
null
);
fail
(
"comparing(f, null) should throw NPE"
);
}
catch
(
NullPointerException
npe
)
{}
try
{
Comparator
<
People
>
cmp
=
Comparator
.
comparing
(
(
Function
<
People
,
String
>)
null
);
Comparator
<
People
>
cmp
=
Comparator
.
comparing
(
null
);
fail
(
"comparing(null) should throw NPE"
);
}
catch
(
NullPointerException
npe
)
{}
try
{
Comparator
<
People
>
cmp
=
Comparator
.
comparing
((
ToIntFunction
<
People
>)
null
);
Comparator
<
People
>
cmp
=
Comparator
.
comparing
Int
(
null
);
fail
(
"comparing(null) should throw NPE"
);
}
catch
(
NullPointerException
npe
)
{}
try
{
Comparator
<
People
>
cmp
=
Comparator
.
comparing
((
ToLongFunction
<
People
>)
null
);
Comparator
<
People
>
cmp
=
Comparator
.
comparing
Long
(
null
);
fail
(
"comparing(null) should throw NPE"
);
}
catch
(
NullPointerException
npe
)
{}
try
{
Comparator
<
People
>
cmp
=
Comparator
.
comparing
((
ToDoubleFunction
<
People
>)
null
);
Comparator
<
People
>
cmp
=
Comparator
.
comparing
Double
(
null
);
fail
(
"comparing(null) should throw NPE"
);
}
catch
(
NullPointerException
npe
)
{}
}
...
...
test/java/util/Map/EntryComparators.java
浏览文件 @
f9ad02d9
...
...
@@ -115,8 +115,8 @@ public class EntryComparators {
// Comparator<People> cmp = Comparator.naturalOrder(); // Should fail to compiler as People is not comparable
// We can use simple comparator, but those have been tested above.
// Thus choose to do compose for some level of interation.
Comparator
<
People
>
cmp1
=
Comparator
.
comparing
(
(
Function
<
People
,
String
>)
People:
:
getFirstName
);
Comparator
<
People
>
cmp2
=
Comparator
.
comparing
(
(
Function
<
People
,
String
>)
People:
:
getLastName
);
Comparator
<
People
>
cmp1
=
Comparator
.
comparing
(
People:
:
getFirstName
);
Comparator
<
People
>
cmp2
=
Comparator
.
comparing
(
People:
:
getLastName
);
Comparator
<
People
>
cmp
=
cmp1
.
thenComparing
(
cmp2
);
assertPairComparison
(
people
[
0
],
people
[
0
],
people
[
1
],
people
[
1
],
...
...
test/java/util/Random/RandomStreamTest.java
浏览文件 @
f9ad02d9
...
...
@@ -82,13 +82,6 @@ public class RandomStreamTest {
assertEquals
(
destination
.
size
(),
count
);
}
@Test
(
dataProvider
=
"suppliers"
)
public
void
testRandomGaussianStream
(
final
Random
random
,
final
int
count
)
{
final
List
<
Double
>
destination
=
new
ArrayList
<>(
count
);
random
.
gaussians
().
limit
(
count
).
forEach
(
destination:
:
add
);
assertEquals
(
destination
.
size
(),
count
);
}
@Test
public
void
testIntStream
()
{
final
long
seed
=
System
.
currentTimeMillis
();
...
...
@@ -131,20 +124,6 @@ public class RandomStreamTest {
assertEquals
(
a
,
b
);
}
@Test
public
void
testGaussianStream
()
{
final
long
seed
=
System
.
currentTimeMillis
();
final
Random
r1
=
new
Random
(
seed
);
final
double
[]
a
=
new
double
[
SIZE
];
for
(
int
i
=
0
;
i
<
SIZE
;
i
++)
{
a
[
i
]
=
r1
.
nextGaussian
();
}
final
Random
r2
=
new
Random
(
seed
);
// same seed
final
double
[]
b
=
r2
.
gaussians
().
limit
(
SIZE
).
toArray
();
assertEquals
(
a
,
b
);
}
@Test
public
void
testThreadLocalIntStream
()
throws
InterruptedException
,
ExecutionException
,
TimeoutException
{
ThreadLocalRandom
tlr
=
ThreadLocalRandom
.
current
();
...
...
@@ -163,12 +142,6 @@ public class RandomStreamTest {
testRandomResultSupplierConcurrently
(()
->
tlr
.
doubles
().
limit
(
SIZE
).
boxed
().
collect
(
toList
()));
}
@Test
public
void
testThreadLocalGaussianStream
()
throws
InterruptedException
,
ExecutionException
,
TimeoutException
{
ThreadLocalRandom
tlr
=
ThreadLocalRandom
.
current
();
testRandomResultSupplierConcurrently
(()
->
tlr
.
gaussians
().
limit
(
SIZE
).
boxed
().
collect
(
toList
()));
}
<
T
>
void
testRandomResultSupplierConcurrently
(
Supplier
<
T
>
s
)
throws
InterruptedException
,
ExecutionException
,
TimeoutException
{
// Produce 10 completable future tasks
final
int
tasks
=
10
;
...
...
test/java/util/Random/RandomTest.java
0 → 100644
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import
org.testng.Assert
;
import
org.testng.annotations.Test
;
import
java.util.Random
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.concurrent.atomic.LongAdder
;
import
java.util.function.BiConsumer
;
import
static
org
.
testng
.
Assert
.*;
/**
* @test
* @run testng RandomTest
* @summary test methods on Random
*/
@Test
public
class
RandomTest
{
// Note: this test was adapted from the 166 TCK ThreadLocalRandomTest test
// and modified to be a TestNG test
/*
* Testing coverage notes:
*
* We don't test randomness properties, but only that repeated
* calls, up to NCALLS tries, produce at least one different
* result. For bounded versions, we sample various intervals
* across multiples of primes.
*/
// max numbers of calls to detect getting stuck on one value
static
final
int
NCALLS
=
10000
;
// max sampled int bound
static
final
int
MAX_INT_BOUND
=
(
1
<<
28
);
// max sampled long bound
static
final
long
MAX_LONG_BOUND
=
(
1L
<<
42
);
// Number of replications for other checks
static
final
int
REPS
=
20
;
/**
* Repeated calls to nextInt produce at least two distinct results
*/
public
void
testNextInt
()
{
Random
r
=
new
Random
();
int
f
=
r
.
nextInt
();
int
i
=
0
;
while
(
i
<
NCALLS
&&
r
.
nextInt
()
==
f
)
++
i
;
assertTrue
(
i
<
NCALLS
);
}
/**
* Repeated calls to nextLong produce at least two distinct results
*/
public
void
testNextLong
()
{
Random
r
=
new
Random
();
long
f
=
r
.
nextLong
();
int
i
=
0
;
while
(
i
<
NCALLS
&&
r
.
nextLong
()
==
f
)
++
i
;
assertTrue
(
i
<
NCALLS
);
}
/**
* Repeated calls to nextBoolean produce at least two distinct results
*/
public
void
testNextBoolean
()
{
Random
r
=
new
Random
();
boolean
f
=
r
.
nextBoolean
();
int
i
=
0
;
while
(
i
<
NCALLS
&&
r
.
nextBoolean
()
==
f
)
++
i
;
assertTrue
(
i
<
NCALLS
);
}
/**
* Repeated calls to nextFloat produce at least two distinct results
*/
public
void
testNextFloat
()
{
Random
r
=
new
Random
();
float
f
=
r
.
nextFloat
();
int
i
=
0
;
while
(
i
<
NCALLS
&&
r
.
nextFloat
()
==
f
)
++
i
;
assertTrue
(
i
<
NCALLS
);
}
/**
* Repeated calls to nextDouble produce at least two distinct results
*/
public
void
testNextDouble
()
{
Random
r
=
new
Random
();
double
f
=
r
.
nextDouble
();
int
i
=
0
;
while
(
i
<
NCALLS
&&
r
.
nextDouble
()
==
f
)
++
i
;
assertTrue
(
i
<
NCALLS
);
}
/**
* Repeated calls to nextGaussian produce at least two distinct results
*/
public
void
testNextGaussian
()
{
Random
r
=
new
Random
();
double
f
=
r
.
nextGaussian
();
int
i
=
0
;
while
(
i
<
NCALLS
&&
r
.
nextGaussian
()
==
f
)
++
i
;
assertTrue
(
i
<
NCALLS
);
}
/**
* nextInt(negative) throws IllegalArgumentException
*/
@Test
(
expectedExceptions
=
IllegalArgumentException
.
class
)
public
void
testNextIntBoundedNeg
()
{
Random
r
=
new
Random
();
int
f
=
r
.
nextInt
(-
17
);
}
/**
* nextInt(bound) returns 0 <= value < bound; repeated calls produce at
* least two distinct results
*/
public
void
testNextIntBounded
()
{
Random
r
=
new
Random
();
// sample bound space across prime number increments
for
(
int
bound
=
2
;
bound
<
MAX_INT_BOUND
;
bound
+=
524959
)
{
int
f
=
r
.
nextInt
(
bound
);
assertTrue
(
0
<=
f
&&
f
<
bound
);
int
i
=
0
;
int
j
;
while
(
i
<
NCALLS
&&
(
j
=
r
.
nextInt
(
bound
))
==
f
)
{
assertTrue
(
0
<=
j
&&
j
<
bound
);
++
i
;
}
assertTrue
(
i
<
NCALLS
);
}
}
/**
* Invoking sized ints, long, doubles, with negative sizes throws
* IllegalArgumentException
*/
public
void
testBadStreamSize
()
{
Random
r
=
new
Random
();
executeAndCatchIAE
(()
->
r
.
ints
(-
1L
));
executeAndCatchIAE
(()
->
r
.
ints
(-
1L
,
2
,
3
));
executeAndCatchIAE
(()
->
r
.
longs
(-
1L
));
executeAndCatchIAE
(()
->
r
.
longs
(-
1L
,
-
1L
,
1L
));
executeAndCatchIAE
(()
->
r
.
doubles
(-
1L
));
executeAndCatchIAE
(()
->
r
.
doubles
(-
1L
,
.
5
,
.
6
));
}
/**
* Invoking bounded ints, long, doubles, with illegal bounds throws
* IllegalArgumentException
*/
public
void
testBadStreamBounds
()
{
Random
r
=
new
Random
();
executeAndCatchIAE
(()
->
r
.
ints
(
2
,
1
));
executeAndCatchIAE
(()
->
r
.
ints
(
10
,
42
,
42
));
executeAndCatchIAE
(()
->
r
.
longs
(-
1L
,
-
1L
));
executeAndCatchIAE
(()
->
r
.
longs
(
10
,
1L
,
-
2L
));
testDoubleBadOriginBound
((
o
,
b
)
->
r
.
doubles
(
10
,
o
,
b
));
}
// An arbitrary finite double value
static
final
double
FINITE
=
Math
.
PI
;
void
testDoubleBadOriginBound
(
BiConsumer
<
Double
,
Double
>
bi
)
{
executeAndCatchIAE
(()
->
bi
.
accept
(
17.0
,
2.0
));
executeAndCatchIAE
(()
->
bi
.
accept
(
0.0
,
0.0
));
executeAndCatchIAE
(()
->
bi
.
accept
(
Double
.
NaN
,
FINITE
));
executeAndCatchIAE
(()
->
bi
.
accept
(
FINITE
,
Double
.
NaN
));
executeAndCatchIAE
(()
->
bi
.
accept
(
Double
.
NEGATIVE_INFINITY
,
Double
.
NEGATIVE_INFINITY
));
// Returns NaN
// executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, FINITE));
// executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
executeAndCatchIAE
(()
->
bi
.
accept
(
FINITE
,
Double
.
NEGATIVE_INFINITY
));
// Returns Double.MAX_VALUE
// executeAndCatchIAE(() -> bi.accept(FINITE, Double.POSITIVE_INFINITY));
executeAndCatchIAE
(()
->
bi
.
accept
(
Double
.
POSITIVE_INFINITY
,
Double
.
NEGATIVE_INFINITY
));
executeAndCatchIAE
(()
->
bi
.
accept
(
Double
.
POSITIVE_INFINITY
,
FINITE
));
executeAndCatchIAE
(()
->
bi
.
accept
(
Double
.
POSITIVE_INFINITY
,
Double
.
POSITIVE_INFINITY
));
}
private
void
executeAndCatchIAE
(
Runnable
r
)
{
executeAndCatch
(
IllegalArgumentException
.
class
,
r
);
}
private
void
executeAndCatch
(
Class
<?
extends
Exception
>
expected
,
Runnable
r
)
{
Exception
caught
=
null
;
try
{
r
.
run
();
}
catch
(
Exception
e
)
{
caught
=
e
;
}
assertNotNull
(
caught
,
String
.
format
(
"No Exception was thrown, expected an Exception of %s to be thrown"
,
expected
.
getName
()));
Assert
.
assertTrue
(
expected
.
isInstance
(
caught
),
String
.
format
(
"Exception thrown %s not an instance of %s"
,
caught
.
getClass
().
getName
(),
expected
.
getName
()));
}
/**
* A sequential sized stream of ints generates the given number of values
*/
public
void
testIntsCount
()
{
LongAdder
counter
=
new
LongAdder
();
Random
r
=
new
Random
();
long
size
=
0
;
for
(
int
reps
=
0
;
reps
<
REPS
;
++
reps
)
{
counter
.
reset
();
r
.
ints
(
size
).
forEach
(
x
->
{
counter
.
increment
();
});
assertEquals
(
counter
.
sum
(),
size
);
size
+=
524959
;
}
}
/**
* A sequential sized stream of longs generates the given number of values
*/
public
void
testLongsCount
()
{
LongAdder
counter
=
new
LongAdder
();
Random
r
=
new
Random
();
long
size
=
0
;
for
(
int
reps
=
0
;
reps
<
REPS
;
++
reps
)
{
counter
.
reset
();
r
.
longs
(
size
).
forEach
(
x
->
{
counter
.
increment
();
});
assertEquals
(
counter
.
sum
(),
size
);
size
+=
524959
;
}
}
/**
* A sequential sized stream of doubles generates the given number of values
*/
public
void
testDoublesCount
()
{
LongAdder
counter
=
new
LongAdder
();
Random
r
=
new
Random
();
long
size
=
0
;
for
(
int
reps
=
0
;
reps
<
REPS
;
++
reps
)
{
counter
.
reset
();
r
.
doubles
(
size
).
forEach
(
x
->
{
counter
.
increment
();
});
assertEquals
(
counter
.
sum
(),
size
);
size
+=
524959
;
}
}
/**
* Each of a sequential sized stream of bounded ints is within bounds
*/
public
void
testBoundedInts
()
{
AtomicInteger
fails
=
new
AtomicInteger
(
0
);
Random
r
=
new
Random
();
long
size
=
12345L
;
for
(
int
least
=
-
15485867
;
least
<
MAX_INT_BOUND
;
least
+=
524959
)
{
for
(
int
bound
=
least
+
2
;
bound
>
least
&&
bound
<
MAX_INT_BOUND
;
bound
+=
67867967
)
{
final
int
lo
=
least
,
hi
=
bound
;
r
.
ints
(
size
,
lo
,
hi
).
forEach
(
x
->
{
if
(
x
<
lo
||
x
>=
hi
)
fails
.
getAndIncrement
();
});
}
}
assertEquals
(
fails
.
get
(),
0
);
}
/**
* Each of a sequential sized stream of bounded longs is within bounds
*/
public
void
testBoundedLongs
()
{
AtomicInteger
fails
=
new
AtomicInteger
(
0
);
Random
r
=
new
Random
();
long
size
=
123L
;
for
(
long
least
=
-
86028121
;
least
<
MAX_LONG_BOUND
;
least
+=
1982451653L
)
{
for
(
long
bound
=
least
+
2
;
bound
>
least
&&
bound
<
MAX_LONG_BOUND
;
bound
+=
Math
.
abs
(
bound
*
7919
))
{
final
long
lo
=
least
,
hi
=
bound
;
r
.
longs
(
size
,
lo
,
hi
).
forEach
(
x
->
{
if
(
x
<
lo
||
x
>=
hi
)
fails
.
getAndIncrement
();
});
}
}
assertEquals
(
fails
.
get
(),
0
);
}
/**
* Each of a sequential sized stream of bounded doubles is within bounds
*/
public
void
testBoundedDoubles
()
{
AtomicInteger
fails
=
new
AtomicInteger
(
0
);
Random
r
=
new
Random
();
long
size
=
456
;
for
(
double
least
=
0.00011
;
least
<
1.0e20
;
least
*=
9
)
{
for
(
double
bound
=
least
*
1.0011
;
bound
<
1.0e20
;
bound
*=
17
)
{
final
double
lo
=
least
,
hi
=
bound
;
r
.
doubles
(
size
,
lo
,
hi
).
forEach
(
x
->
{
if
(
x
<
lo
||
x
>=
hi
)
fails
.
getAndIncrement
();
});
}
}
assertEquals
(
fails
.
get
(),
0
);
}
/**
* A parallel unsized stream of ints generates at least 100 values
*/
public
void
testUnsizedIntsCount
()
{
LongAdder
counter
=
new
LongAdder
();
Random
r
=
new
Random
();
long
size
=
100
;
r
.
ints
().
limit
(
size
).
parallel
().
forEach
(
x
->
{
counter
.
increment
();
});
assertEquals
(
counter
.
sum
(),
size
);
}
/**
* A parallel unsized stream of longs generates at least 100 values
*/
public
void
testUnsizedLongsCount
()
{
LongAdder
counter
=
new
LongAdder
();
Random
r
=
new
Random
();
long
size
=
100
;
r
.
longs
().
limit
(
size
).
parallel
().
forEach
(
x
->
{
counter
.
increment
();
});
assertEquals
(
counter
.
sum
(),
size
);
}
/**
* A parallel unsized stream of doubles generates at least 100 values
*/
public
void
testUnsizedDoublesCount
()
{
LongAdder
counter
=
new
LongAdder
();
Random
r
=
new
Random
();
long
size
=
100
;
r
.
doubles
().
limit
(
size
).
parallel
().
forEach
(
x
->
{
counter
.
increment
();
});
assertEquals
(
counter
.
sum
(),
size
);
}
/**
* A sequential unsized stream of ints generates at least 100 values
*/
public
void
testUnsizedIntsCountSeq
()
{
LongAdder
counter
=
new
LongAdder
();
Random
r
=
new
Random
();
long
size
=
100
;
r
.
ints
().
limit
(
size
).
forEach
(
x
->
{
counter
.
increment
();
});
assertEquals
(
counter
.
sum
(),
size
);
}
/**
* A sequential unsized stream of longs generates at least 100 values
*/
public
void
testUnsizedLongsCountSeq
()
{
LongAdder
counter
=
new
LongAdder
();
Random
r
=
new
Random
();
long
size
=
100
;
r
.
longs
().
limit
(
size
).
forEach
(
x
->
{
counter
.
increment
();
});
assertEquals
(
counter
.
sum
(),
size
);
}
/**
* A sequential unsized stream of doubles generates at least 100 values
*/
public
void
testUnsizedDoublesCountSeq
()
{
LongAdder
counter
=
new
LongAdder
();
Random
r
=
new
Random
();
long
size
=
100
;
r
.
doubles
().
limit
(
size
).
forEach
(
x
->
{
counter
.
increment
();
});
assertEquals
(
counter
.
sum
(),
size
);
}
}
test/java/util/SplittableRandom/SplittableRandomTest.java
0 → 100644
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import
org.testng.Assert
;
import
org.testng.annotations.Test
;
import
java.util.SplittableRandom
;
import
java.util.concurrent.ThreadLocalRandom
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.concurrent.atomic.LongAdder
;
import
java.util.function.BiConsumer
;
import
static
org
.
testng
.
Assert
.
assertEquals
;
import
static
org
.
testng
.
Assert
.
assertNotNull
;
import
static
org
.
testng
.
AssertJUnit
.
assertTrue
;
/**
* @test
* @run testng SplittableRandomTest
* @run testng/othervm -Djava.util.secureRandomSeed=true SplittableRandomTest
* @summary test methods on SplittableRandom
*/
@Test
public
class
SplittableRandomTest
{
// Note: this test was copied from the 166 TCK SplittableRandomTest test
// and modified to be a TestNG test
/*
* Testing coverage notes:
*
* 1. Many of the test methods are adapted from ThreadLocalRandomTest.
*
* 2. These tests do not check for random number generator quality.
* But we check for minimal API compliance by requiring that
* repeated calls to nextX methods, up to NCALLS tries, produce at
* least two distinct results. (In some possible universe, a
* "correct" implementation might fail, but the odds are vastly
* less than that of encountering a hardware failure while running
* the test.) For bounded nextX methods, we sample various
* intervals across multiples of primes. In other tests, we repeat
* under REPS different values.
*/
// max numbers of calls to detect getting stuck on one value
static
final
int
NCALLS
=
10000
;
// max sampled int bound
static
final
int
MAX_INT_BOUND
=
(
1
<<
28
);
// max sampled long bound
static
final
long
MAX_LONG_BOUND
=
(
1L
<<
42
);
// Number of replications for other checks
static
final
int
REPS
=
20
;
/**
* Repeated calls to nextInt produce at least two distinct results
*/
public
void
testNextInt
()
{
SplittableRandom
sr
=
new
SplittableRandom
();
int
f
=
sr
.
nextInt
();
int
i
=
0
;
while
(
i
<
NCALLS
&&
sr
.
nextInt
()
==
f
)
++
i
;
assertTrue
(
i
<
NCALLS
);
}
/**
* Repeated calls to nextLong produce at least two distinct results
*/
public
void
testNextLong
()
{
SplittableRandom
sr
=
new
SplittableRandom
();
long
f
=
sr
.
nextLong
();
int
i
=
0
;
while
(
i
<
NCALLS
&&
sr
.
nextLong
()
==
f
)
++
i
;
assertTrue
(
i
<
NCALLS
);
}
/**
* Repeated calls to nextDouble produce at least two distinct results
*/
public
void
testNextDouble
()
{
SplittableRandom
sr
=
new
SplittableRandom
();
double
f
=
sr
.
nextDouble
();
int
i
=
0
;
while
(
i
<
NCALLS
&&
sr
.
nextDouble
()
==
f
)
++
i
;
assertTrue
(
i
<
NCALLS
);
}
/**
* Two SplittableRandoms created with the same seed produce the
* same values for nextLong.
*/
public
void
testSeedConstructor
()
{
for
(
long
seed
=
2
;
seed
<
MAX_LONG_BOUND
;
seed
+=
15485863
)
{
SplittableRandom
sr1
=
new
SplittableRandom
(
seed
);
SplittableRandom
sr2
=
new
SplittableRandom
(
seed
);
for
(
int
i
=
0
;
i
<
REPS
;
++
i
)
assertEquals
(
sr1
.
nextLong
(),
sr2
.
nextLong
());
}
}
/**
* A SplittableRandom produced by split() of a default-constructed
* SplittableRandom generates a different sequence
*/
public
void
testSplit1
()
{
SplittableRandom
sr
=
new
SplittableRandom
();
for
(
int
reps
=
0
;
reps
<
REPS
;
++
reps
)
{
SplittableRandom
sc
=
sr
.
split
();
int
i
=
0
;
while
(
i
<
NCALLS
&&
sr
.
nextLong
()
==
sc
.
nextLong
())
++
i
;
assertTrue
(
i
<
NCALLS
);
}
}
/**
* A SplittableRandom produced by split() of a seeded-constructed
* SplittableRandom generates a different sequence
*/
public
void
testSplit2
()
{
SplittableRandom
sr
=
new
SplittableRandom
(
12345
);
for
(
int
reps
=
0
;
reps
<
REPS
;
++
reps
)
{
SplittableRandom
sc
=
sr
.
split
();
int
i
=
0
;
while
(
i
<
NCALLS
&&
sr
.
nextLong
()
==
sc
.
nextLong
())
++
i
;
assertTrue
(
i
<
NCALLS
);
}
}
/**
* nextInt(negative) throws IllegalArgumentException
*/
@Test
(
expectedExceptions
=
IllegalArgumentException
.
class
)
public
void
testNextIntBoundedNeg
()
{
SplittableRandom
sr
=
new
SplittableRandom
();
int
f
=
sr
.
nextInt
(-
17
);
}
/**
* nextInt(least >= bound) throws IllegalArgumentException
*/
@Test
(
expectedExceptions
=
IllegalArgumentException
.
class
)
public
void
testNextIntBadBounds
()
{
SplittableRandom
sr
=
new
SplittableRandom
();
int
f
=
sr
.
nextInt
(
17
,
2
);
}
/**
* nextInt(bound) returns 0 <= value < bound;
* repeated calls produce at least two distinct results
*/
public
void
testNextIntBounded
()
{
SplittableRandom
sr
=
new
SplittableRandom
();
// sample bound space across prime number increments
for
(
int
bound
=
2
;
bound
<
MAX_INT_BOUND
;
bound
+=
524959
)
{
int
f
=
sr
.
nextInt
(
bound
);
assertTrue
(
0
<=
f
&&
f
<
bound
);
int
i
=
0
;
int
j
;
while
(
i
<
NCALLS
&&
(
j
=
sr
.
nextInt
(
bound
))
==
f
)
{
assertTrue
(
0
<=
j
&&
j
<
bound
);
++
i
;
}
assertTrue
(
i
<
NCALLS
);
}
}
/**
* nextInt(least, bound) returns least <= value < bound;
* repeated calls produce at least two distinct results
*/
public
void
testNextIntBounded2
()
{
SplittableRandom
sr
=
new
SplittableRandom
();
for
(
int
least
=
-
15485863
;
least
<
MAX_INT_BOUND
;
least
+=
524959
)
{
for
(
int
bound
=
least
+
2
;
bound
>
least
&&
bound
<
MAX_INT_BOUND
;
bound
+=
49979687
)
{
int
f
=
sr
.
nextInt
(
least
,
bound
);
assertTrue
(
least
<=
f
&&
f
<
bound
);
int
i
=
0
;
int
j
;
while
(
i
<
NCALLS
&&
(
j
=
sr
.
nextInt
(
least
,
bound
))
==
f
)
{
assertTrue
(
least
<=
j
&&
j
<
bound
);
++
i
;
}
assertTrue
(
i
<
NCALLS
);
}
}
}
/**
* nextLong(negative) throws IllegalArgumentException
*/
@Test
(
expectedExceptions
=
IllegalArgumentException
.
class
)
public
void
testNextLongBoundedNeg
()
{
SplittableRandom
sr
=
new
SplittableRandom
();
long
f
=
sr
.
nextLong
(-
17
);
}
/**
* nextLong(least >= bound) throws IllegalArgumentException
*/
@Test
(
expectedExceptions
=
IllegalArgumentException
.
class
)
public
void
testNextLongBadBounds
()
{
SplittableRandom
sr
=
new
SplittableRandom
();
long
f
=
sr
.
nextLong
(
17
,
2
);
}
/**
* nextLong(bound) returns 0 <= value < bound;
* repeated calls produce at least two distinct results
*/
public
void
testNextLongBounded
()
{
SplittableRandom
sr
=
new
SplittableRandom
();
for
(
long
bound
=
2
;
bound
<
MAX_LONG_BOUND
;
bound
+=
15485863
)
{
long
f
=
sr
.
nextLong
(
bound
);
assertTrue
(
0
<=
f
&&
f
<
bound
);
int
i
=
0
;
long
j
;
while
(
i
<
NCALLS
&&
(
j
=
sr
.
nextLong
(
bound
))
==
f
)
{
assertTrue
(
0
<=
j
&&
j
<
bound
);
++
i
;
}
assertTrue
(
i
<
NCALLS
);
}
}
/**
* nextLong(least, bound) returns least <= value < bound;
* repeated calls produce at least two distinct results
*/
public
void
testNextLongBounded2
()
{
SplittableRandom
sr
=
new
SplittableRandom
();
for
(
long
least
=
-
86028121
;
least
<
MAX_LONG_BOUND
;
least
+=
982451653L
)
{
for
(
long
bound
=
least
+
2
;
bound
>
least
&&
bound
<
MAX_LONG_BOUND
;
bound
+=
Math
.
abs
(
bound
*
7919
))
{
long
f
=
sr
.
nextLong
(
least
,
bound
);
assertTrue
(
least
<=
f
&&
f
<
bound
);
int
i
=
0
;
long
j
;
while
(
i
<
NCALLS
&&
(
j
=
sr
.
nextLong
(
least
,
bound
))
==
f
)
{
assertTrue
(
least
<=
j
&&
j
<
bound
);
++
i
;
}
assertTrue
(
i
<
NCALLS
);
}
}
}
/**
* nextDouble(bound) throws IllegalArgumentException
*/
public
void
testNextDoubleBadBound
()
{
SplittableRandom
sr
=
new
SplittableRandom
();
executeAndCatchIAE
(()
->
sr
.
nextDouble
(
0.0
));
executeAndCatchIAE
(()
->
sr
.
nextDouble
(-
0.0
));
executeAndCatchIAE
(()
->
sr
.
nextDouble
(+
0.0
));
executeAndCatchIAE
(()
->
sr
.
nextDouble
(-
1.0
));
executeAndCatchIAE
(()
->
sr
.
nextDouble
(
Double
.
NaN
));
executeAndCatchIAE
(()
->
sr
.
nextDouble
(
Double
.
NEGATIVE_INFINITY
));
// Returns Double.MAX_VALUE
// executeAndCatchIAE(() -> r.nextDouble(Double.POSITIVE_INFINITY));
}
/**
* nextDouble(origin, bound) throws IllegalArgumentException
*/
public
void
testNextDoubleBadOriginBound
()
{
testDoubleBadOriginBound
(
new
SplittableRandom
()::
nextDouble
);
}
// An arbitrary finite double value
static
final
double
FINITE
=
Math
.
PI
;
void
testDoubleBadOriginBound
(
BiConsumer
<
Double
,
Double
>
bi
)
{
executeAndCatchIAE
(()
->
bi
.
accept
(
17.0
,
2.0
));
executeAndCatchIAE
(()
->
bi
.
accept
(
0.0
,
0.0
));
executeAndCatchIAE
(()
->
bi
.
accept
(
Double
.
NaN
,
FINITE
));
executeAndCatchIAE
(()
->
bi
.
accept
(
FINITE
,
Double
.
NaN
));
executeAndCatchIAE
(()
->
bi
.
accept
(
Double
.
NEGATIVE_INFINITY
,
Double
.
NEGATIVE_INFINITY
));
// Returns NaN
// executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, FINITE));
// executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
executeAndCatchIAE
(()
->
bi
.
accept
(
FINITE
,
Double
.
NEGATIVE_INFINITY
));
// Returns Double.MAX_VALUE
// executeAndCatchIAE(() -> bi.accept(FINITE, Double.POSITIVE_INFINITY));
executeAndCatchIAE
(()
->
bi
.
accept
(
Double
.
POSITIVE_INFINITY
,
Double
.
NEGATIVE_INFINITY
));
executeAndCatchIAE
(()
->
bi
.
accept
(
Double
.
POSITIVE_INFINITY
,
FINITE
));
executeAndCatchIAE
(()
->
bi
.
accept
(
Double
.
POSITIVE_INFINITY
,
Double
.
POSITIVE_INFINITY
));
}
/**
* nextDouble(least, bound) returns least <= value < bound;
* repeated calls produce at least two distinct results
*/
public
void
testNextDoubleBounded2
()
{
SplittableRandom
sr
=
new
SplittableRandom
();
for
(
double
least
=
0.0001
;
least
<
1.0e20
;
least
*=
8
)
{
for
(
double
bound
=
least
*
1.001
;
bound
<
1.0e20
;
bound
*=
16
)
{
double
f
=
sr
.
nextDouble
(
least
,
bound
);
assertTrue
(
least
<=
f
&&
f
<
bound
);
int
i
=
0
;
double
j
;
while
(
i
<
NCALLS
&&
(
j
=
sr
.
nextDouble
(
least
,
bound
))
==
f
)
{
assertTrue
(
least
<=
j
&&
j
<
bound
);
++
i
;
}
assertTrue
(
i
<
NCALLS
);
}
}
}
/**
* Invoking sized ints, long, doubles, with negative sizes throws
* IllegalArgumentException
*/
public
void
testBadStreamSize
()
{
SplittableRandom
r
=
new
SplittableRandom
();
executeAndCatchIAE
(()
->
r
.
ints
(-
1L
));
executeAndCatchIAE
(()
->
r
.
ints
(-
1L
,
2
,
3
));
executeAndCatchIAE
(()
->
r
.
longs
(-
1L
));
executeAndCatchIAE
(()
->
r
.
longs
(-
1L
,
-
1L
,
1L
));
executeAndCatchIAE
(()
->
r
.
doubles
(-
1L
));
executeAndCatchIAE
(()
->
r
.
doubles
(-
1L
,
.
5
,
.
6
));
}
/**
* Invoking bounded ints, long, doubles, with illegal bounds throws
* IllegalArgumentException
*/
public
void
testBadStreamBounds
()
{
SplittableRandom
r
=
new
SplittableRandom
();
executeAndCatchIAE
(()
->
r
.
ints
(
2
,
1
));
executeAndCatchIAE
(()
->
r
.
ints
(
10
,
42
,
42
));
executeAndCatchIAE
(()
->
r
.
longs
(-
1L
,
-
1L
));
executeAndCatchIAE
(()
->
r
.
longs
(
10
,
1L
,
-
2L
));
testDoubleBadOriginBound
((
o
,
b
)
->
r
.
doubles
(
10
,
o
,
b
));
}
private
void
executeAndCatchIAE
(
Runnable
r
)
{
executeAndCatch
(
IllegalArgumentException
.
class
,
r
);
}
private
void
executeAndCatch
(
Class
<?
extends
Exception
>
expected
,
Runnable
r
)
{
Exception
caught
=
null
;
try
{
r
.
run
();
}
catch
(
Exception
e
)
{
caught
=
e
;
}
assertNotNull
(
caught
,
String
.
format
(
"No Exception was thrown, expected an Exception of %s to be thrown"
,
expected
.
getName
()));
Assert
.
assertTrue
(
expected
.
isInstance
(
caught
),
String
.
format
(
"Exception thrown %s not an instance of %s"
,
caught
.
getClass
().
getName
(),
expected
.
getName
()));
}
/**
* A parallel sized stream of ints generates the given number of values
*/
public
void
testIntsCount
()
{
LongAdder
counter
=
new
LongAdder
();
SplittableRandom
r
=
new
SplittableRandom
();
long
size
=
0
;
for
(
int
reps
=
0
;
reps
<
REPS
;
++
reps
)
{
counter
.
reset
();
r
.
ints
(
size
).
parallel
().
forEach
(
x
->
{
counter
.
increment
();});
assertEquals
(
counter
.
sum
(),
size
);
size
+=
524959
;
}
}
/**
* A parallel sized stream of longs generates the given number of values
*/
public
void
testLongsCount
()
{
LongAdder
counter
=
new
LongAdder
();
SplittableRandom
r
=
new
SplittableRandom
();
long
size
=
0
;
for
(
int
reps
=
0
;
reps
<
REPS
;
++
reps
)
{
counter
.
reset
();
r
.
longs
(
size
).
parallel
().
forEach
(
x
->
{
counter
.
increment
();});
assertEquals
(
counter
.
sum
(),
size
);
size
+=
524959
;
}
}
/**
* A parallel sized stream of doubles generates the given number of values
*/
public
void
testDoublesCount
()
{
LongAdder
counter
=
new
LongAdder
();
SplittableRandom
r
=
new
SplittableRandom
();
long
size
=
0
;
for
(
int
reps
=
0
;
reps
<
REPS
;
++
reps
)
{
counter
.
reset
();
r
.
doubles
(
size
).
parallel
().
forEach
(
x
->
{
counter
.
increment
();});
assertEquals
(
counter
.
sum
(),
size
);
size
+=
524959
;
}
}
/**
* Each of a parallel sized stream of bounded ints is within bounds
*/
public
void
testBoundedInts
()
{
AtomicInteger
fails
=
new
AtomicInteger
(
0
);
SplittableRandom
r
=
new
SplittableRandom
();
long
size
=
12345L
;
for
(
int
least
=
-
15485867
;
least
<
MAX_INT_BOUND
;
least
+=
524959
)
{
for
(
int
bound
=
least
+
2
;
bound
>
least
&&
bound
<
MAX_INT_BOUND
;
bound
+=
67867967
)
{
final
int
lo
=
least
,
hi
=
bound
;
r
.
ints
(
size
,
lo
,
hi
).
parallel
().
forEach
(
x
->
{
if
(
x
<
lo
||
x
>=
hi
)
fails
.
getAndIncrement
();
});
}
}
assertEquals
(
fails
.
get
(),
0
);
}
/**
* Each of a parallel sized stream of bounded longs is within bounds
*/
public
void
testBoundedLongs
()
{
AtomicInteger
fails
=
new
AtomicInteger
(
0
);
SplittableRandom
r
=
new
SplittableRandom
();
long
size
=
123L
;
for
(
long
least
=
-
86028121
;
least
<
MAX_LONG_BOUND
;
least
+=
1982451653L
)
{
for
(
long
bound
=
least
+
2
;
bound
>
least
&&
bound
<
MAX_LONG_BOUND
;
bound
+=
Math
.
abs
(
bound
*
7919
))
{
final
long
lo
=
least
,
hi
=
bound
;
r
.
longs
(
size
,
lo
,
hi
).
parallel
().
forEach
(
x
->
{
if
(
x
<
lo
||
x
>=
hi
)
fails
.
getAndIncrement
();
});
}
}
assertEquals
(
fails
.
get
(),
0
);
}
/**
* Each of a parallel sized stream of bounded doubles is within bounds
*/
public
void
testBoundedDoubles
()
{
AtomicInteger
fails
=
new
AtomicInteger
(
0
);
SplittableRandom
r
=
new
SplittableRandom
();
long
size
=
456
;
for
(
double
least
=
0.00011
;
least
<
1.0e20
;
least
*=
9
)
{
for
(
double
bound
=
least
*
1.0011
;
bound
<
1.0e20
;
bound
*=
17
)
{
final
double
lo
=
least
,
hi
=
bound
;
r
.
doubles
(
size
,
lo
,
hi
).
parallel
().
forEach
(
x
->
{
if
(
x
<
lo
||
x
>=
hi
)
fails
.
getAndIncrement
();
});
}
}
assertEquals
(
fails
.
get
(),
0
);
}
/**
* A parallel unsized stream of ints generates at least 100 values
*/
public
void
testUnsizedIntsCount
()
{
LongAdder
counter
=
new
LongAdder
();
SplittableRandom
r
=
new
SplittableRandom
();
long
size
=
100
;
r
.
ints
().
limit
(
size
).
parallel
().
forEach
(
x
->
{
counter
.
increment
();});
assertEquals
(
counter
.
sum
(),
size
);
}
/**
* A parallel unsized stream of longs generates at least 100 values
*/
public
void
testUnsizedLongsCount
()
{
LongAdder
counter
=
new
LongAdder
();
SplittableRandom
r
=
new
SplittableRandom
();
long
size
=
100
;
r
.
longs
().
limit
(
size
).
parallel
().
forEach
(
x
->
{
counter
.
increment
();});
assertEquals
(
counter
.
sum
(),
size
);
}
/**
* A parallel unsized stream of doubles generates at least 100 values
*/
public
void
testUnsizedDoublesCount
()
{
LongAdder
counter
=
new
LongAdder
();
SplittableRandom
r
=
new
SplittableRandom
();
long
size
=
100
;
r
.
doubles
().
limit
(
size
).
parallel
().
forEach
(
x
->
{
counter
.
increment
();});
assertEquals
(
counter
.
sum
(),
size
);
}
/**
* A sequential unsized stream of ints generates at least 100 values
*/
public
void
testUnsizedIntsCountSeq
()
{
LongAdder
counter
=
new
LongAdder
();
SplittableRandom
r
=
new
SplittableRandom
();
long
size
=
100
;
r
.
ints
().
limit
(
size
).
forEach
(
x
->
{
counter
.
increment
();});
assertEquals
(
counter
.
sum
(),
size
);
}
/**
* A sequential unsized stream of longs generates at least 100 values
*/
public
void
testUnsizedLongsCountSeq
()
{
LongAdder
counter
=
new
LongAdder
();
SplittableRandom
r
=
new
SplittableRandom
();
long
size
=
100
;
r
.
longs
().
limit
(
size
).
forEach
(
x
->
{
counter
.
increment
();});
assertEquals
(
counter
.
sum
(),
size
);
}
/**
* A sequential unsized stream of doubles generates at least 100 values
*/
public
void
testUnsizedDoublesCountSeq
()
{
LongAdder
counter
=
new
LongAdder
();
SplittableRandom
r
=
new
SplittableRandom
();
long
size
=
100
;
r
.
doubles
().
limit
(
size
).
forEach
(
x
->
{
counter
.
increment
();});
assertEquals
(
counter
.
sum
(),
size
);
}
}
test/java/util/concurrent/ThreadLocalRandom/ThreadLocalRandomTest.java
0 → 100644
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import
org.testng.Assert
;
import
org.testng.annotations.Test
;
import
java.util.concurrent.ThreadLocalRandom
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.concurrent.atomic.LongAdder
;
import
java.util.function.BiConsumer
;
import
static
org
.
testng
.
Assert
.*;
/**
* @test
* @run testng ThreadLocalRandomTest
* @summary test methods on ThreadLocalRandom
*/
@Test
public
class
ThreadLocalRandomTest
{
// Note: this test was copied from the 166 TCK ThreadLocalRandomTest test
// and modified to be a TestNG test
/*
* Testing coverage notes:
*
* We don't test randomness properties, but only that repeated
* calls, up to NCALLS tries, produce at least one different
* result. For bounded versions, we sample various intervals
* across multiples of primes.
*/
// max numbers of calls to detect getting stuck on one value
static
final
int
NCALLS
=
10000
;
// max sampled int bound
static
final
int
MAX_INT_BOUND
=
(
1
<<
28
);
// max sampled long bound
static
final
long
MAX_LONG_BOUND
=
(
1L
<<
42
);
// Number of replications for other checks
static
final
int
REPS
=
20
;
/**
* setSeed throws UnsupportedOperationException
*/
@Test
(
expectedExceptions
=
UnsupportedOperationException
.
class
)
public
void
testSetSeed
()
{
ThreadLocalRandom
.
current
().
setSeed
(
17
);
}
/**
* Repeated calls to nextInt produce at least two distinct results
*/
public
void
testNextInt
()
{
int
f
=
ThreadLocalRandom
.
current
().
nextInt
();
int
i
=
0
;
while
(
i
<
NCALLS
&&
ThreadLocalRandom
.
current
().
nextInt
()
==
f
)
++
i
;
assertTrue
(
i
<
NCALLS
);
}
/**
* Repeated calls to nextLong produce at least two distinct results
*/
public
void
testNextLong
()
{
long
f
=
ThreadLocalRandom
.
current
().
nextLong
();
int
i
=
0
;
while
(
i
<
NCALLS
&&
ThreadLocalRandom
.
current
().
nextLong
()
==
f
)
++
i
;
assertTrue
(
i
<
NCALLS
);
}
/**
* Repeated calls to nextBoolean produce at least two distinct results
*/
public
void
testNextBoolean
()
{
boolean
f
=
ThreadLocalRandom
.
current
().
nextBoolean
();
int
i
=
0
;
while
(
i
<
NCALLS
&&
ThreadLocalRandom
.
current
().
nextBoolean
()
==
f
)
++
i
;
assertTrue
(
i
<
NCALLS
);
}
/**
* Repeated calls to nextFloat produce at least two distinct results
*/
public
void
testNextFloat
()
{
float
f
=
ThreadLocalRandom
.
current
().
nextFloat
();
int
i
=
0
;
while
(
i
<
NCALLS
&&
ThreadLocalRandom
.
current
().
nextFloat
()
==
f
)
++
i
;
assertTrue
(
i
<
NCALLS
);
}
/**
* Repeated calls to nextDouble produce at least two distinct results
*/
public
void
testNextDouble
()
{
double
f
=
ThreadLocalRandom
.
current
().
nextDouble
();
int
i
=
0
;
while
(
i
<
NCALLS
&&
ThreadLocalRandom
.
current
().
nextDouble
()
==
f
)
++
i
;
assertTrue
(
i
<
NCALLS
);
}
/**
* Repeated calls to nextGaussian produce at least two distinct results
*/
public
void
testNextGaussian
()
{
double
f
=
ThreadLocalRandom
.
current
().
nextGaussian
();
int
i
=
0
;
while
(
i
<
NCALLS
&&
ThreadLocalRandom
.
current
().
nextGaussian
()
==
f
)
++
i
;
assertTrue
(
i
<
NCALLS
);
}
/**
* nextInt(negative) throws IllegalArgumentException
*/
@Test
(
expectedExceptions
=
IllegalArgumentException
.
class
)
public
void
testNextIntBoundedNeg
()
{
int
f
=
ThreadLocalRandom
.
current
().
nextInt
(-
17
);
}
/**
* nextInt(least >= bound) throws IllegalArgumentException
*/
@Test
(
expectedExceptions
=
IllegalArgumentException
.
class
)
public
void
testNextIntBadBounds
()
{
int
f
=
ThreadLocalRandom
.
current
().
nextInt
(
17
,
2
);
}
/**
* nextInt(bound) returns 0 <= value < bound; repeated calls produce at
* least two distinct results
*/
public
void
testNextIntBounded
()
{
// sample bound space across prime number increments
for
(
int
bound
=
2
;
bound
<
MAX_INT_BOUND
;
bound
+=
524959
)
{
int
f
=
ThreadLocalRandom
.
current
().
nextInt
(
bound
);
assertTrue
(
0
<=
f
&&
f
<
bound
);
int
i
=
0
;
int
j
;
while
(
i
<
NCALLS
&&
(
j
=
ThreadLocalRandom
.
current
().
nextInt
(
bound
))
==
f
)
{
assertTrue
(
0
<=
j
&&
j
<
bound
);
++
i
;
}
assertTrue
(
i
<
NCALLS
);
}
}
/**
* nextInt(least, bound) returns least <= value < bound; repeated calls
* produce at least two distinct results
*/
public
void
testNextIntBounded2
()
{
for
(
int
least
=
-
15485863
;
least
<
MAX_INT_BOUND
;
least
+=
524959
)
{
for
(
int
bound
=
least
+
2
;
bound
>
least
&&
bound
<
MAX_INT_BOUND
;
bound
+=
49979687
)
{
int
f
=
ThreadLocalRandom
.
current
().
nextInt
(
least
,
bound
);
assertTrue
(
least
<=
f
&&
f
<
bound
);
int
i
=
0
;
int
j
;
while
(
i
<
NCALLS
&&
(
j
=
ThreadLocalRandom
.
current
().
nextInt
(
least
,
bound
))
==
f
)
{
assertTrue
(
least
<=
j
&&
j
<
bound
);
++
i
;
}
assertTrue
(
i
<
NCALLS
);
}
}
}
/**
* nextLong(negative) throws IllegalArgumentException
*/
@Test
(
expectedExceptions
=
IllegalArgumentException
.
class
)
public
void
testNextLongBoundedNeg
()
{
long
f
=
ThreadLocalRandom
.
current
().
nextLong
(-
17
);
}
/**
* nextLong(least >= bound) throws IllegalArgumentException
*/
@Test
(
expectedExceptions
=
IllegalArgumentException
.
class
)
public
void
testNextLongBadBounds
()
{
long
f
=
ThreadLocalRandom
.
current
().
nextLong
(
17
,
2
);
}
/**
* nextLong(bound) returns 0 <= value < bound; repeated calls produce at
* least two distinct results
*/
public
void
testNextLongBounded
()
{
for
(
long
bound
=
2
;
bound
<
MAX_LONG_BOUND
;
bound
+=
15485863
)
{
long
f
=
ThreadLocalRandom
.
current
().
nextLong
(
bound
);
assertTrue
(
0
<=
f
&&
f
<
bound
);
int
i
=
0
;
long
j
;
while
(
i
<
NCALLS
&&
(
j
=
ThreadLocalRandom
.
current
().
nextLong
(
bound
))
==
f
)
{
assertTrue
(
0
<=
j
&&
j
<
bound
);
++
i
;
}
assertTrue
(
i
<
NCALLS
);
}
}
/**
* nextLong(least, bound) returns least <= value < bound; repeated calls
* produce at least two distinct results
*/
public
void
testNextLongBounded2
()
{
for
(
long
least
=
-
86028121
;
least
<
MAX_LONG_BOUND
;
least
+=
982451653L
)
{
for
(
long
bound
=
least
+
2
;
bound
>
least
&&
bound
<
MAX_LONG_BOUND
;
bound
+=
Math
.
abs
(
bound
*
7919
))
{
long
f
=
ThreadLocalRandom
.
current
().
nextLong
(
least
,
bound
);
assertTrue
(
least
<=
f
&&
f
<
bound
);
int
i
=
0
;
long
j
;
while
(
i
<
NCALLS
&&
(
j
=
ThreadLocalRandom
.
current
().
nextLong
(
least
,
bound
))
==
f
)
{
assertTrue
(
least
<=
j
&&
j
<
bound
);
++
i
;
}
assertTrue
(
i
<
NCALLS
);
}
}
}
/**
* nextDouble(bound) throws IllegalArgumentException
*/
public
void
testNextDoubleBadBound
()
{
ThreadLocalRandom
r
=
ThreadLocalRandom
.
current
();
executeAndCatchIAE
(()
->
r
.
nextDouble
(
0.0
));
executeAndCatchIAE
(()
->
r
.
nextDouble
(-
0.0
));
executeAndCatchIAE
(()
->
r
.
nextDouble
(+
0.0
));
executeAndCatchIAE
(()
->
r
.
nextDouble
(-
1.0
));
executeAndCatchIAE
(()
->
r
.
nextDouble
(
Double
.
NaN
));
executeAndCatchIAE
(()
->
r
.
nextDouble
(
Double
.
NEGATIVE_INFINITY
));
// Returns Double.MAX_VALUE
// executeAndCatchIAE(() -> r.nextDouble(Double.POSITIVE_INFINITY));
}
/**
* nextDouble(origin, bound) throws IllegalArgumentException
*/
public
void
testNextDoubleBadOriginBound
()
{
testDoubleBadOriginBound
(
ThreadLocalRandom
.
current
()::
nextDouble
);
}
// An arbitrary finite double value
static
final
double
FINITE
=
Math
.
PI
;
void
testDoubleBadOriginBound
(
BiConsumer
<
Double
,
Double
>
bi
)
{
executeAndCatchIAE
(()
->
bi
.
accept
(
17.0
,
2.0
));
executeAndCatchIAE
(()
->
bi
.
accept
(
0.0
,
0.0
));
executeAndCatchIAE
(()
->
bi
.
accept
(
Double
.
NaN
,
FINITE
));
executeAndCatchIAE
(()
->
bi
.
accept
(
FINITE
,
Double
.
NaN
));
executeAndCatchIAE
(()
->
bi
.
accept
(
Double
.
NEGATIVE_INFINITY
,
Double
.
NEGATIVE_INFINITY
));
// Returns NaN
// executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, FINITE));
// executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
executeAndCatchIAE
(()
->
bi
.
accept
(
FINITE
,
Double
.
NEGATIVE_INFINITY
));
// Returns Double.MAX_VALUE
// executeAndCatchIAE(() -> bi.accept(FINITE, Double.POSITIVE_INFINITY));
executeAndCatchIAE
(()
->
bi
.
accept
(
Double
.
POSITIVE_INFINITY
,
Double
.
NEGATIVE_INFINITY
));
executeAndCatchIAE
(()
->
bi
.
accept
(
Double
.
POSITIVE_INFINITY
,
FINITE
));
executeAndCatchIAE
(()
->
bi
.
accept
(
Double
.
POSITIVE_INFINITY
,
Double
.
POSITIVE_INFINITY
));
}
/**
* nextDouble(least, bound) returns least <= value < bound; repeated calls
* produce at least two distinct results
*/
public
void
testNextDoubleBounded2
()
{
for
(
double
least
=
0.0001
;
least
<
1.0e20
;
least
*=
8
)
{
for
(
double
bound
=
least
*
1.001
;
bound
<
1.0e20
;
bound
*=
16
)
{
double
f
=
ThreadLocalRandom
.
current
().
nextDouble
(
least
,
bound
);
assertTrue
(
least
<=
f
&&
f
<
bound
);
int
i
=
0
;
double
j
;
while
(
i
<
NCALLS
&&
(
j
=
ThreadLocalRandom
.
current
().
nextDouble
(
least
,
bound
))
==
f
)
{
assertTrue
(
least
<=
j
&&
j
<
bound
);
++
i
;
}
assertTrue
(
i
<
NCALLS
);
}
}
}
/**
* Invoking sized ints, long, doubles, with negative sizes throws
* IllegalArgumentException
*/
public
void
testBadStreamSize
()
{
ThreadLocalRandom
r
=
ThreadLocalRandom
.
current
();
executeAndCatchIAE
(()
->
r
.
ints
(-
1L
));
executeAndCatchIAE
(()
->
r
.
ints
(-
1L
,
2
,
3
));
executeAndCatchIAE
(()
->
r
.
longs
(-
1L
));
executeAndCatchIAE
(()
->
r
.
longs
(-
1L
,
-
1L
,
1L
));
executeAndCatchIAE
(()
->
r
.
doubles
(-
1L
));
executeAndCatchIAE
(()
->
r
.
doubles
(-
1L
,
.
5
,
.
6
));
}
/**
* Invoking bounded ints, long, doubles, with illegal bounds throws
* IllegalArgumentException
*/
public
void
testBadStreamBounds
()
{
ThreadLocalRandom
r
=
ThreadLocalRandom
.
current
();
executeAndCatchIAE
(()
->
r
.
ints
(
2
,
1
));
executeAndCatchIAE
(()
->
r
.
ints
(
10
,
42
,
42
));
executeAndCatchIAE
(()
->
r
.
longs
(-
1L
,
-
1L
));
executeAndCatchIAE
(()
->
r
.
longs
(
10
,
1L
,
-
2L
));
testDoubleBadOriginBound
((
o
,
b
)
->
r
.
doubles
(
10
,
o
,
b
));
}
private
void
executeAndCatchIAE
(
Runnable
r
)
{
executeAndCatch
(
IllegalArgumentException
.
class
,
r
);
}
private
void
executeAndCatch
(
Class
<?
extends
Exception
>
expected
,
Runnable
r
)
{
Exception
caught
=
null
;
try
{
r
.
run
();
}
catch
(
Exception
e
)
{
caught
=
e
;
}
assertNotNull
(
caught
,
String
.
format
(
"No Exception was thrown, expected an Exception of %s to be thrown"
,
expected
.
getName
()));
Assert
.
assertTrue
(
expected
.
isInstance
(
caught
),
String
.
format
(
"Exception thrown %s not an instance of %s"
,
caught
.
getClass
().
getName
(),
expected
.
getName
()));
}
/**
* A parallel sized stream of ints generates the given number of values
*/
public
void
testIntsCount
()
{
LongAdder
counter
=
new
LongAdder
();
ThreadLocalRandom
r
=
ThreadLocalRandom
.
current
();
long
size
=
0
;
for
(
int
reps
=
0
;
reps
<
REPS
;
++
reps
)
{
counter
.
reset
();
r
.
ints
(
size
).
parallel
().
forEach
(
x
->
{
counter
.
increment
();
});
assertEquals
(
counter
.
sum
(),
size
);
size
+=
524959
;
}
}
/**
* A parallel sized stream of longs generates the given number of values
*/
public
void
testLongsCount
()
{
LongAdder
counter
=
new
LongAdder
();
ThreadLocalRandom
r
=
ThreadLocalRandom
.
current
();
long
size
=
0
;
for
(
int
reps
=
0
;
reps
<
REPS
;
++
reps
)
{
counter
.
reset
();
r
.
longs
(
size
).
parallel
().
forEach
(
x
->
{
counter
.
increment
();
});
assertEquals
(
counter
.
sum
(),
size
);
size
+=
524959
;
}
}
/**
* A parallel sized stream of doubles generates the given number of values
*/
public
void
testDoublesCount
()
{
LongAdder
counter
=
new
LongAdder
();
ThreadLocalRandom
r
=
ThreadLocalRandom
.
current
();
long
size
=
0
;
for
(
int
reps
=
0
;
reps
<
REPS
;
++
reps
)
{
counter
.
reset
();
r
.
doubles
(
size
).
parallel
().
forEach
(
x
->
{
counter
.
increment
();
});
assertEquals
(
counter
.
sum
(),
size
);
size
+=
524959
;
}
}
/**
* Each of a parallel sized stream of bounded ints is within bounds
*/
public
void
testBoundedInts
()
{
AtomicInteger
fails
=
new
AtomicInteger
(
0
);
ThreadLocalRandom
r
=
ThreadLocalRandom
.
current
();
long
size
=
12345L
;
for
(
int
least
=
-
15485867
;
least
<
MAX_INT_BOUND
;
least
+=
524959
)
{
for
(
int
bound
=
least
+
2
;
bound
>
least
&&
bound
<
MAX_INT_BOUND
;
bound
+=
67867967
)
{
final
int
lo
=
least
,
hi
=
bound
;
r
.
ints
(
size
,
lo
,
hi
).
parallel
().
forEach
(
x
->
{
if
(
x
<
lo
||
x
>=
hi
)
fails
.
getAndIncrement
();
});
}
}
assertEquals
(
fails
.
get
(),
0
);
}
/**
* Each of a parallel sized stream of bounded longs is within bounds
*/
public
void
testBoundedLongs
()
{
AtomicInteger
fails
=
new
AtomicInteger
(
0
);
ThreadLocalRandom
r
=
ThreadLocalRandom
.
current
();
long
size
=
123L
;
for
(
long
least
=
-
86028121
;
least
<
MAX_LONG_BOUND
;
least
+=
1982451653L
)
{
for
(
long
bound
=
least
+
2
;
bound
>
least
&&
bound
<
MAX_LONG_BOUND
;
bound
+=
Math
.
abs
(
bound
*
7919
))
{
final
long
lo
=
least
,
hi
=
bound
;
r
.
longs
(
size
,
lo
,
hi
).
parallel
().
forEach
(
x
->
{
if
(
x
<
lo
||
x
>=
hi
)
fails
.
getAndIncrement
();
});
}
}
assertEquals
(
fails
.
get
(),
0
);
}
/**
* Each of a parallel sized stream of bounded doubles is within bounds
*/
public
void
testBoundedDoubles
()
{
AtomicInteger
fails
=
new
AtomicInteger
(
0
);
ThreadLocalRandom
r
=
ThreadLocalRandom
.
current
();
long
size
=
456
;
for
(
double
least
=
0.00011
;
least
<
1.0e20
;
least
*=
9
)
{
for
(
double
bound
=
least
*
1.0011
;
bound
<
1.0e20
;
bound
*=
17
)
{
final
double
lo
=
least
,
hi
=
bound
;
r
.
doubles
(
size
,
lo
,
hi
).
parallel
().
forEach
(
x
->
{
if
(
x
<
lo
||
x
>=
hi
)
fails
.
getAndIncrement
();
});
}
}
assertEquals
(
fails
.
get
(),
0
);
}
/**
* A parallel unsized stream of ints generates at least 100 values
*/
public
void
testUnsizedIntsCount
()
{
LongAdder
counter
=
new
LongAdder
();
ThreadLocalRandom
r
=
ThreadLocalRandom
.
current
();
long
size
=
100
;
r
.
ints
().
limit
(
size
).
parallel
().
forEach
(
x
->
{
counter
.
increment
();
});
assertEquals
(
counter
.
sum
(),
size
);
}
/**
* A parallel unsized stream of longs generates at least 100 values
*/
public
void
testUnsizedLongsCount
()
{
LongAdder
counter
=
new
LongAdder
();
ThreadLocalRandom
r
=
ThreadLocalRandom
.
current
();
long
size
=
100
;
r
.
longs
().
limit
(
size
).
parallel
().
forEach
(
x
->
{
counter
.
increment
();
});
assertEquals
(
counter
.
sum
(),
size
);
}
/**
* A parallel unsized stream of doubles generates at least 100 values
*/
public
void
testUnsizedDoublesCount
()
{
LongAdder
counter
=
new
LongAdder
();
ThreadLocalRandom
r
=
ThreadLocalRandom
.
current
();
long
size
=
100
;
r
.
doubles
().
limit
(
size
).
parallel
().
forEach
(
x
->
{
counter
.
increment
();
});
assertEquals
(
counter
.
sum
(),
size
);
}
/**
* A sequential unsized stream of ints generates at least 100 values
*/
public
void
testUnsizedIntsCountSeq
()
{
LongAdder
counter
=
new
LongAdder
();
ThreadLocalRandom
r
=
ThreadLocalRandom
.
current
();
long
size
=
100
;
r
.
ints
().
limit
(
size
).
forEach
(
x
->
{
counter
.
increment
();
});
assertEquals
(
counter
.
sum
(),
size
);
}
/**
* A sequential unsized stream of longs generates at least 100 values
*/
public
void
testUnsizedLongsCountSeq
()
{
LongAdder
counter
=
new
LongAdder
();
ThreadLocalRandom
r
=
ThreadLocalRandom
.
current
();
long
size
=
100
;
r
.
longs
().
limit
(
size
).
forEach
(
x
->
{
counter
.
increment
();
});
assertEquals
(
counter
.
sum
(),
size
);
}
/**
* A sequential unsized stream of doubles generates at least 100 values
*/
public
void
testUnsizedDoublesCountSeq
()
{
LongAdder
counter
=
new
LongAdder
();
ThreadLocalRandom
r
=
ThreadLocalRandom
.
current
();
long
size
=
100
;
r
.
doubles
().
limit
(
size
).
forEach
(
x
->
{
counter
.
increment
();
});
assertEquals
(
counter
.
sum
(),
size
);
}
}
test/java/util/concurrent/locks/StampedLock/ReadersUnlockAfterWriteUnlock.java
0 → 100644
浏览文件 @
f9ad02d9
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @run main/othervm/timeout=60 ReadersUnlockAfterWriteUnlock
* @bug 8023234
* @summary StampedLock serializes readers on writer unlock
* @author Dmitry Chyuko
* @author Aleksey Shipilev
*/
import
java.util.concurrent.CyclicBarrier
;
import
java.util.concurrent.locks.StampedLock
;
public
class
ReadersUnlockAfterWriteUnlock
{
static
final
int
RNUM
=
2
;
static
final
StampedLock
sl
=
new
StampedLock
();
static
volatile
boolean
isDone
;
static
CyclicBarrier
iterationStart
=
new
CyclicBarrier
(
RNUM
+
1
);
static
CyclicBarrier
readersHaveLocks
=
new
CyclicBarrier
(
RNUM
);
static
CyclicBarrier
writerHasLock
=
new
CyclicBarrier
(
RNUM
+
1
);
static
class
Reader
extends
Thread
{
final
String
name
;
Reader
(
String
name
)
{
super
();
this
.
name
=
name
;
}
public
void
run
()
{
while
(!
isDone
&&
!
isInterrupted
())
{
try
{
iterationStart
.
await
();
writerHasLock
.
await
();
long
rs
=
sl
.
readLock
();
// single reader blocks here indefinitely if readers
// are serialized
readersHaveLocks
.
await
();
sl
.
unlockRead
(
rs
);
}
catch
(
Exception
e
)
{
throw
new
IllegalStateException
(
e
);
}
}
}
}
public
static
void
main
(
String
[]
args
)
throws
InterruptedException
{
for
(
int
r
=
0
;
r
<
RNUM
;
++
r
)
{
new
Reader
(
"r"
+
r
).
start
();
}
int
i
;
for
(
i
=
0
;
i
<
1024
;
++
i
)
{
try
{
iterationStart
.
await
();
long
ws
=
sl
.
writeLock
();
writerHasLock
.
await
();
Thread
.
sleep
(
10
);
sl
.
unlockWrite
(
ws
);
}
catch
(
Exception
e
)
{
throw
new
IllegalStateException
(
e
);
}
}
isDone
=
true
;
}
}
test/java/util/function/BinaryOperator/BasicTest.java
浏览文件 @
f9ad02d9
...
...
@@ -67,26 +67,26 @@ public class BasicTest {
};
public
void
testMaxBy
()
{
Comparator
<
People
>
cmp
=
Comparator
.
comparing
(
(
Function
<
People
,
String
>)
People:
:
getFirstName
);
Comparator
<
People
>
cmp
=
Comparator
.
comparing
(
People:
:
getFirstName
);
// lesser
assertSame
(
maxBy
(
cmp
).
apply
(
people
[
0
],
people
[
1
]),
people
[
1
]);
// euqal
cmp
=
Comparator
.
comparing
(
(
Function
<
People
,
String
>)
People:
:
getLastName
);
cmp
=
Comparator
.
comparing
(
People:
:
getLastName
);
assertSame
(
maxBy
(
cmp
).
apply
(
people
[
0
],
people
[
1
]),
people
[
0
]);
// greater
cmp
=
Comparator
.
comparing
((
ToIntFunction
<
People
>)
People:
:
getAge
);
cmp
=
Comparator
.
comparing
Int
(
People:
:
getAge
);
assertSame
(
maxBy
(
cmp
).
apply
(
people
[
0
],
people
[
1
]),
people
[
0
]);
}
public
void
test
LesserOf
()
{
Comparator
<
People
>
cmp
=
Comparator
.
comparing
(
(
Function
<
People
,
String
>)
People:
:
getFirstName
);
public
void
test
MinBy
()
{
Comparator
<
People
>
cmp
=
Comparator
.
comparing
(
People:
:
getFirstName
);
// lesser
assertSame
(
minBy
(
cmp
).
apply
(
people
[
0
],
people
[
1
]),
people
[
0
]);
// euqal
cmp
=
Comparator
.
comparing
(
(
Function
<
People
,
String
>)
People:
:
getLastName
);
cmp
=
Comparator
.
comparing
(
People:
:
getLastName
);
assertSame
(
minBy
(
cmp
).
apply
(
people
[
0
],
people
[
1
]),
people
[
0
]);
// greater
cmp
=
Comparator
.
comparing
((
ToIntFunction
<
People
>)
People:
:
getAge
);
cmp
=
Comparator
.
comparing
Int
(
People:
:
getAge
);
assertSame
(
minBy
(
cmp
).
apply
(
people
[
0
],
people
[
1
]),
people
[
1
]);
}
...
...
test/java/util/logging/Logger/getLogger/TestLogger.java
0 → 100644
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.logging.Logger
;
/**
* @test
* @bug 8005899
* @build TestLogger testlogger.MyResource
* @run main/othervm TestLogger
* @run main/othervm -Dsecurity=on TestLogger
**/
public
class
TestLogger
{
public
static
final
String
RESOURCE_BUNDLE
=
"testlogger.MyResource"
;
public
static
final
String
ORG_LOGGER
=
"org"
;
public
static
final
String
FOO_LOGGER
=
ORG_LOGGER
+
".foo.Foo"
;
public
static
final
String
BAR_LOGGER
=
ORG_LOGGER
+
".bar.Bar"
;
public
static
final
String
GEE_LOGGER
=
ORG_LOGGER
+
".gee.Gee"
;
public
static
final
String
GEE_GEE_LOGGER
=
GEE_LOGGER
+
".Gee"
;
public
static
void
main
(
String
[]
args
)
{
final
String
security
=
System
.
getProperty
(
"security"
,
"off"
);
System
.
out
.
println
(
"Security is "
+
security
);
if
(
"on"
.
equals
(
security
))
{
System
.
setSecurityManager
(
new
SecurityManager
());
}
newLogger
(
FOO_LOGGER
,
RESOURCE_BUNDLE
);
newLogger
(
FOO_LOGGER
);
newLogger
(
BAR_LOGGER
);
newLogger
(
BAR_LOGGER
,
RESOURCE_BUNDLE
);
newLogger
(
GEE_LOGGER
,
null
);
newLogger
(
GEE_LOGGER
,
RESOURCE_BUNDLE
);
newLogger
(
ORG_LOGGER
);
newLogger
(
GEE_GEE_LOGGER
);
for
(
String
log
:
new
String
[]
{
FOO_LOGGER
,
BAR_LOGGER
,
GEE_LOGGER
})
{
if
(!
RESOURCE_BUNDLE
.
equals
(
Logger
.
getLogger
(
log
).
getResourceBundleName
()))
{
throw
new
RuntimeException
(
"Shouldn't allow to reset the resource bundle for "
+
log
);
}
try
{
Logger
logger
=
Logger
.
getLogger
(
log
,
null
);
if
(!
RESOURCE_BUNDLE
.
equals
(
logger
.
getResourceBundleName
()))
{
throw
new
RuntimeException
(
"Shouldn't allow to reset the resource bundle for "
+
log
);
}
throw
new
RuntimeException
(
"Expected IllegalArgumentException not thrown for "
+
log
);
}
catch
(
IllegalArgumentException
e
)
{
System
.
out
.
println
(
"Got expected exception for "
+
log
+
": "
+
e
);
}
}
for
(
String
log
:
new
String
[]
{
ORG_LOGGER
,
GEE_GEE_LOGGER
})
{
if
(
Logger
.
getLogger
(
log
).
getResourceBundleName
()
!=
null
)
{
throw
new
RuntimeException
(
"Resource bundle is not null for log: "
+
Logger
.
getLogger
(
log
).
getResourceBundleName
());
}
try
{
Logger
logger
=
Logger
.
getLogger
(
log
,
null
);
if
(
logger
.
getResourceBundleName
()
!=
null
)
{
throw
new
RuntimeException
(
"Resource bundle is not null for log: "
+
logger
.
getResourceBundleName
());
}
System
.
out
.
println
(
"Success calling Logger.getLogger(\""
+
log
+
"\", null)"
);
}
catch
(
IllegalArgumentException
e
)
{
throw
new
RuntimeException
(
"Unexpected exception for "
+
log
+
": "
+
e
,
e
);
}
}
}
private
static
List
<
Logger
>
strongRefs
=
new
ArrayList
<>();
private
static
void
newLogger
(
String
name
)
{
strongRefs
.
add
(
Logger
.
getLogger
(
name
));
}
private
static
void
newLogger
(
String
name
,
String
resourceBundleName
)
{
strongRefs
.
add
(
Logger
.
getLogger
(
name
,
resourceBundleName
));
}
}
src/share/classes/sun/misc/Compar
e.java
→
test/java/util/logging/Logger/getLogger/testlogger/MyResourc
e.java
浏览文件 @
f9ad02d9
/*
* Copyright (c)
1996, 1997
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c)
2013
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
...
...
@@ -22,25 +20,33 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
testlogger
;
import
java.util.ArrayList
;
import
java.util.Enumeration
;
import
java.util.HashMap
;
import
java.util.Hashtable
;
import
java.util.Map
;
import
java.util.Properties
;
import
java.util.ResourceBundle
;
/**
* Compare: an interface to enable users to define the result of
* a comparison of two objects.
*
* @author Sunita Mani
* A dummy resource bundle for testing purposes.
* @author danielfuchs
*/
public
class
MyResource
extends
ResourceBundle
{
Map
<
String
,
Object
>
bundle
=
new
HashMap
<>();
package
sun.misc
;
public
interface
Compare
{
@Override
protected
Object
handleGetObject
(
String
key
)
{
bundle
.
put
(
key
,
"Localized: "
+
key
);
return
bundle
.
get
(
key
);
}
/**
* doCompare
*
* @param obj1 first object to compare.
* @param obj2 second object to compare.
* @return -1 if obj1 < obj2, 0 if obj1 == obj2, 1 if obj1 > obj2.
*/
public
int
doCompare
(
Object
obj1
,
Object
obj2
);
@Override
public
Enumeration
<
String
>
getKeys
()
{
final
Hashtable
<
String
,
Object
>
h
=
new
Hashtable
<>(
bundle
);
return
h
.
keys
();
}
}
test/java/util/regex/PatternTest.java
0 → 100644
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @summary Unit tests for wrapping classes should delegate to default methods
* @library ../stream/bootlib
* @build java.util.stream.OpTestCase
* @run testng/othervm PatternTest
*/
import
org.testng.annotations.DataProvider
;
import
org.testng.annotations.Test
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.function.Supplier
;
import
java.util.regex.Pattern
;
import
java.util.stream.LambdaTestHelpers
;
import
java.util.stream.OpTestCase
;
import
java.util.stream.Stream
;
import
java.util.stream.TestData
;
@Test
public
class
PatternTest
extends
OpTestCase
{
@DataProvider
(
name
=
"Stream<String>"
)
public
static
Object
[][]
makeStreamTestData
()
{
List
<
Object
[]>
data
=
new
ArrayList
<>();
String
description
=
""
;
String
input
=
"awgqwefg1fefw4vssv1vvv1"
;
Pattern
pattern
=
Pattern
.
compile
(
"4"
);
List
<
String
>
expected
=
new
ArrayList
<>();
expected
.
add
(
"awgqwefg1fefw"
);
expected
.
add
(
"vssv1vvv1"
);
// Must match the type signature of the consumer of this data, testStrings
// String, String, Pattern, List<String>
data
.
add
(
new
Object
[]{
description
,
input
,
pattern
,
expected
});
input
=
"afbfq\u00a3abgwgb\u00a3awngnwggw\u00a3a\u00a3ahjrnhneerh"
;
pattern
=
Pattern
.
compile
(
"\u00a3a"
);
expected
=
new
ArrayList
<>();
expected
.
add
(
"afbfq"
);
expected
.
add
(
"bgwgb"
);
expected
.
add
(
"wngnwggw"
);
expected
.
add
(
""
);
expected
.
add
(
"hjrnhneerh"
);
data
.
add
(
new
Object
[]{
description
,
input
,
pattern
,
expected
});
input
=
"awgqwefg1fefw4vssv1vvv1"
;
pattern
=
Pattern
.
compile
(
"1"
);
expected
=
new
ArrayList
<>();
expected
.
add
(
"awgqwefg"
);
expected
.
add
(
"fefw4vssv"
);
expected
.
add
(
"vvv"
);
data
.
add
(
new
Object
[]{
description
,
input
,
pattern
,
expected
});
input
=
"a\u4ebafg1fefw\u4eba4\u9f9cvssv\u9f9c1v\u672c\u672cvv"
;
pattern
=
Pattern
.
compile
(
"1"
);
expected
=
new
ArrayList
<>();
expected
.
add
(
"a\u4ebafg"
);
expected
.
add
(
"fefw\u4eba4\u9f9cvssv\u9f9c"
);
expected
.
add
(
"v\u672c\u672cvv"
);
data
.
add
(
new
Object
[]{
description
,
input
,
pattern
,
expected
});
input
=
"1\u56da23\u56da456\u56da7890"
;
pattern
=
Pattern
.
compile
(
"\u56da"
);
expected
=
new
ArrayList
<>();
expected
.
add
(
"1"
);
expected
.
add
(
"23"
);
expected
.
add
(
"456"
);
expected
.
add
(
"7890"
);
data
.
add
(
new
Object
[]{
description
,
input
,
pattern
,
expected
});
input
=
"1\u56da23\u9f9c\u672c\u672c\u56da456\u56da\u9f9c\u672c7890"
;
pattern
=
Pattern
.
compile
(
"\u56da"
);
expected
=
new
ArrayList
<>();
expected
.
add
(
"1"
);
expected
.
add
(
"23\u9f9c\u672c\u672c"
);
expected
.
add
(
"456"
);
expected
.
add
(
"\u9f9c\u672c7890"
);
data
.
add
(
new
Object
[]{
description
,
input
,
pattern
,
expected
});
input
=
""
;
pattern
=
Pattern
.
compile
(
"\u56da"
);
expected
=
new
ArrayList
<>();
data
.
add
(
new
Object
[]{
description
,
input
,
pattern
,
expected
});
description
=
"Multiple separators"
;
input
=
"This is,testing: with\tdifferent separators."
;
pattern
=
Pattern
.
compile
(
"[ \t,:.]"
);
expected
=
new
ArrayList
<>();
expected
.
add
(
"This"
);
expected
.
add
(
"is"
);
expected
.
add
(
"testing"
);
expected
.
add
(
""
);
expected
.
add
(
"with"
);
expected
.
add
(
"different"
);
expected
.
add
(
"separators"
);
data
.
add
(
new
Object
[]
{
description
,
input
,
pattern
,
expected
});
return
data
.
toArray
(
new
Object
[
0
][]);
}
@Test
(
dataProvider
=
"Stream<String>"
)
public
void
testStrings
(
String
description
,
String
input
,
Pattern
pattern
,
List
<
String
>
expected
)
{
Supplier
<
Stream
<
String
>>
ss
=
()
->
pattern
.
splitAsStream
(
input
);
withData
(
TestData
.
Factory
.
ofSupplier
(
description
,
ss
))
.
stream
(
LambdaTestHelpers
.
identity
())
.
expectedResult
(
expected
)
.
exercise
();
}
}
test/java/util/regex/RegExTest.java
浏览文件 @
f9ad02d9
...
...
@@ -33,7 +33,7 @@
* 5013885 5003322 4988891 5098443 5110268 6173522 4829857 5027748 6376940
* 6358731 6178785 6284152 6231989 6497148 6486934 6233084 6504326 6635133
* 6350801 6676425 6878475 6919132 6931676 6948903 6990617 7014645 7039066
* 7067045 7014640 7189363 8007395 8013252 8013254 8012646
* 7067045 7014640 7189363 8007395 8013252 8013254 8012646
8023647
*/
import
java.util.regex.*
;
...
...
@@ -146,6 +146,7 @@ public class RegExTest {
linebreakTest
();
branchTest
();
groupCurlyNotFoundSuppTest
();
groupCurlyBackoffTest
();
patternAsPredicate
();
if
(
failure
)
{
throw
new
...
...
@@ -3999,6 +4000,15 @@ public class RegExTest {
report
(
"GroupCurly NotFoundSupp"
);
}
// This test is for 8023647
private
static
void
groupCurlyBackoffTest
()
throws
Exception
{
if
(!
"abc1c"
.
matches
(
"(\\w)+1\\1"
)
||
"abc11"
.
matches
(
"(\\w)+1\\1"
))
{
failCount
++;
}
report
(
"GroupCurly backoff"
);
}
// This test is for 8012646
private
static
void
patternAsPredicate
()
throws
Exception
{
Predicate
<
String
>
p
=
Pattern
.
compile
(
"[a-z]+"
).
asPredicate
();
...
...
test/java/util/stream/test/org/openjdk/tests/java/util/SplittableRandomTest.java
0 → 100644
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
org.openjdk.tests.java.util
;
import
org.testng.annotations.DataProvider
;
import
org.testng.annotations.Test
;
import
java.util.ArrayList
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.Spliterator
;
import
java.util.SplittableRandom
;
import
java.util.function.Consumer
;
import
java.util.function.Function
;
import
java.util.stream.DoubleStream
;
import
java.util.stream.DoubleStreamTestScenario
;
import
java.util.stream.IntStream
;
import
java.util.stream.IntStreamTestScenario
;
import
java.util.stream.LongStream
;
import
java.util.stream.LongStreamTestScenario
;
import
java.util.stream.OpTestCase
;
import
java.util.stream.StreamSupport
;
import
java.util.stream.TestData
;
@Test
public
class
SplittableRandomTest
extends
OpTestCase
{
static
class
RandomBoxedSpliterator
<
T
>
implements
Spliterator
<
T
>
{
final
SplittableRandom
rng
;
long
index
;
final
long
fence
;
final
Function
<
SplittableRandom
,
T
>
rngF
;
RandomBoxedSpliterator
(
SplittableRandom
rng
,
long
index
,
long
fence
,
Function
<
SplittableRandom
,
T
>
rngF
)
{
this
.
rng
=
rng
;
this
.
index
=
index
;
this
.
fence
=
fence
;
this
.
rngF
=
rngF
;
}
public
RandomBoxedSpliterator
<
T
>
trySplit
()
{
long
i
=
index
,
m
=
(
i
+
fence
)
>>>
1
;
return
(
m
<=
i
)
?
null
:
new
RandomBoxedSpliterator
<>(
rng
.
split
(),
i
,
index
=
m
,
rngF
);
}
public
long
estimateSize
()
{
return
fence
-
index
;
}
public
int
characteristics
()
{
return
(
Spliterator
.
SIZED
|
Spliterator
.
SUBSIZED
|
Spliterator
.
NONNULL
|
Spliterator
.
IMMUTABLE
);
}
@Override
public
boolean
tryAdvance
(
Consumer
<?
super
T
>
consumer
)
{
if
(
consumer
==
null
)
throw
new
NullPointerException
();
long
i
=
index
,
f
=
fence
;
if
(
i
<
f
)
{
consumer
.
accept
(
rngF
.
apply
(
rng
));
index
=
i
+
1
;
return
true
;
}
return
false
;
}
}
static
final
int
SIZE
=
1
<<
16
;
// Ensure there is a range of a power of 2
static
final
int
[]
BOUNDS
=
{
256
};
static
final
int
[]
ORIGINS
=
{-
16
,
0
,
16
};
static
<
T
extends
Comparable
<
T
>>
ResultAsserter
<
Iterable
<
T
>>
randomAsserter
(
int
size
,
T
origin
,
T
bound
)
{
return
(
act
,
exp
,
ord
,
par
)
->
{
int
count
=
0
;
Set
<
Comparable
<
T
>>
values
=
new
HashSet
<>();
for
(
Comparable
<
T
>
t
:
act
)
{
if
(
origin
.
compareTo
(
bound
)
<
0
)
{
assertTrue
(
t
.
compareTo
(
origin
)
>=
0
);
assertTrue
(
t
.
compareTo
(
bound
)
<
0
);
}
values
.
add
(
t
);
count
++;
}
assertEquals
(
count
,
size
);
// Assert that at least one different result is produced
// For the size of the data it is highly improbable that this
// will cause a false negative (i.e. a false failure)
assertTrue
(
values
.
size
()
>
1
);
};
}
@DataProvider
(
name
=
"ints"
)
public
static
Object
[][]
intsDataProvider
()
{
List
<
Object
[]>
data
=
new
ArrayList
<>();
// Function to create a stream using a RandomBoxedSpliterator
Function
<
Function
<
SplittableRandom
,
Integer
>,
IntStream
>
rbsf
=
sf
->
StreamSupport
.
stream
(
new
RandomBoxedSpliterator
<>(
new
SplittableRandom
(),
0
,
SIZE
,
sf
),
false
).
mapToInt
(
i
->
i
);
// Unbounded
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofIntSupplier
(
String
.
format
(
"new SplittableRandom().ints().limit(%d)"
,
SIZE
),
()
->
new
SplittableRandom
().
ints
().
limit
(
SIZE
)),
randomAsserter
(
SIZE
,
Integer
.
MAX_VALUE
,
0
)
});
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofIntSupplier
(
String
.
format
(
"new SplittableRandom().ints(%d)"
,
SIZE
),
()
->
new
SplittableRandom
().
ints
(
SIZE
)),
randomAsserter
(
SIZE
,
Integer
.
MAX_VALUE
,
0
)
});
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofIntSupplier
(
String
.
format
(
"new RandomBoxedSpliterator(0, %d, sr -> sr.nextInt())"
,
SIZE
),
()
->
rbsf
.
apply
(
sr
->
sr
.
nextInt
())),
randomAsserter
(
SIZE
,
Integer
.
MAX_VALUE
,
0
)
});
// Bounded
for
(
int
b
:
BOUNDS
)
{
for
(
int
o
:
ORIGINS
)
{
final
int
origin
=
o
;
final
int
bound
=
b
;
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofIntSupplier
(
String
.
format
(
"new SplittableRandom().ints(%d, %d).limit(%d)"
,
origin
,
bound
,
SIZE
),
()
->
new
SplittableRandom
().
ints
(
origin
,
bound
).
limit
(
SIZE
)),
randomAsserter
(
SIZE
,
origin
,
bound
)
});
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofIntSupplier
(
String
.
format
(
"new SplittableRandom().ints(%d, %d, %d)"
,
SIZE
,
origin
,
bound
),
()
->
new
SplittableRandom
().
ints
(
SIZE
,
origin
,
bound
)),
randomAsserter
(
SIZE
,
origin
,
bound
)
});
if
(
origin
==
0
)
{
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofIntSupplier
(
String
.
format
(
"new RandomBoxedSpliterator(0, %d, sr -> sr.nextInt(%d))"
,
SIZE
,
bound
),
()
->
rbsf
.
apply
(
sr
->
sr
.
nextInt
(
bound
))),
randomAsserter
(
SIZE
,
origin
,
bound
)
});
}
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofIntSupplier
(
String
.
format
(
"new RandomBoxedSpliterator(0, %d, sr -> sr.nextInt(%d, %d))"
,
SIZE
,
origin
,
bound
),
()
->
rbsf
.
apply
(
sr
->
sr
.
nextInt
(
origin
,
bound
))),
randomAsserter
(
SIZE
,
origin
,
bound
)
});
}
}
return
data
.
toArray
(
new
Object
[
0
][]);
}
@Test
(
dataProvider
=
"ints"
)
public
void
testInts
(
TestData
.
OfInt
data
,
ResultAsserter
<
Iterable
<
Integer
>>
ra
)
{
withData
(
data
).
stream
(
s
->
s
).
without
(
IntStreamTestScenario
.
PAR_STREAM_TO_ARRAY_CLEAR_SIZED
).
resultAsserter
(
ra
).
exercise
();
}
@DataProvider
(
name
=
"longs"
)
public
static
Object
[][]
longsDataProvider
()
{
List
<
Object
[]>
data
=
new
ArrayList
<>();
// Function to create a stream using a RandomBoxedSpliterator
Function
<
Function
<
SplittableRandom
,
Long
>,
LongStream
>
rbsf
=
sf
->
StreamSupport
.
stream
(
new
RandomBoxedSpliterator
<>(
new
SplittableRandom
(),
0
,
SIZE
,
sf
),
false
).
mapToLong
(
i
->
i
);
// Unbounded
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofLongSupplier
(
String
.
format
(
"new SplittableRandom().longs().limit(%d)"
,
SIZE
),
()
->
new
SplittableRandom
().
longs
().
limit
(
SIZE
)),
randomAsserter
(
SIZE
,
Long
.
MAX_VALUE
,
0L
)
});
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofLongSupplier
(
String
.
format
(
"new SplittableRandom().longs(%d)"
,
SIZE
),
()
->
new
SplittableRandom
().
longs
(
SIZE
)),
randomAsserter
(
SIZE
,
Long
.
MAX_VALUE
,
0L
)
});
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofLongSupplier
(
String
.
format
(
"new RandomBoxedSpliterator(0, %d, sr -> sr.nextLong())"
,
SIZE
),
()
->
rbsf
.
apply
(
sr
->
sr
.
nextLong
())),
randomAsserter
(
SIZE
,
Long
.
MAX_VALUE
,
0L
)
});
// Bounded
for
(
int
b
:
BOUNDS
)
{
for
(
int
o
:
ORIGINS
)
{
final
long
origin
=
o
;
final
long
bound
=
b
;
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofLongSupplier
(
String
.
format
(
"new SplittableRandom().longs(%d, %d).limit(%d)"
,
origin
,
bound
,
SIZE
),
()
->
new
SplittableRandom
().
longs
(
origin
,
bound
).
limit
(
SIZE
)),
randomAsserter
(
SIZE
,
origin
,
bound
)
});
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofLongSupplier
(
String
.
format
(
"new SplittableRandom().longs(%d, %d, %d)"
,
SIZE
,
origin
,
bound
),
()
->
new
SplittableRandom
().
longs
(
SIZE
,
origin
,
bound
)),
randomAsserter
(
SIZE
,
origin
,
bound
)
});
if
(
origin
==
0
)
{
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofLongSupplier
(
String
.
format
(
"new RandomBoxedSpliterator(0, %d, sr -> sr.nextLong(%d))"
,
SIZE
,
bound
),
()
->
rbsf
.
apply
(
sr
->
sr
.
nextLong
(
bound
))),
randomAsserter
(
SIZE
,
origin
,
bound
)
});
}
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofLongSupplier
(
String
.
format
(
"new RandomBoxedSpliterator(0, %d, sr -> sr.nextLong(%d, %d))"
,
SIZE
,
origin
,
bound
),
()
->
rbsf
.
apply
(
sr
->
sr
.
nextLong
(
origin
,
bound
))),
randomAsserter
(
SIZE
,
origin
,
bound
)
});
}
}
return
data
.
toArray
(
new
Object
[
0
][]);
}
@Test
(
dataProvider
=
"longs"
)
public
void
testLongs
(
TestData
.
OfLong
data
,
ResultAsserter
<
Iterable
<
Long
>>
ra
)
{
withData
(
data
).
stream
(
s
->
s
).
without
(
LongStreamTestScenario
.
PAR_STREAM_TO_ARRAY_CLEAR_SIZED
).
resultAsserter
(
ra
).
exercise
();
}
@DataProvider
(
name
=
"doubles"
)
public
static
Object
[][]
doublesDataProvider
()
{
List
<
Object
[]>
data
=
new
ArrayList
<>();
// Function to create a stream using a RandomBoxedSpliterator
Function
<
Function
<
SplittableRandom
,
Double
>,
DoubleStream
>
rbsf
=
sf
->
StreamSupport
.
stream
(
new
RandomBoxedSpliterator
<>(
new
SplittableRandom
(),
0
,
SIZE
,
sf
),
false
).
mapToDouble
(
i
->
i
);
// Unbounded
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofDoubleSupplier
(
String
.
format
(
"new SplittableRandom().doubles().limit(%d)"
,
SIZE
),
()
->
new
SplittableRandom
().
doubles
().
limit
(
SIZE
)),
randomAsserter
(
SIZE
,
Double
.
MAX_VALUE
,
0
d
)
});
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofDoubleSupplier
(
String
.
format
(
"new SplittableRandom().doubles(%d)"
,
SIZE
),
()
->
new
SplittableRandom
().
doubles
(
SIZE
)),
randomAsserter
(
SIZE
,
Double
.
MAX_VALUE
,
0
d
)
});
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofDoubleSupplier
(
String
.
format
(
"new RandomBoxedSpliterator(0, %d, sr -> sr.nextDouble())"
,
SIZE
),
()
->
rbsf
.
apply
(
sr
->
sr
.
nextDouble
())),
randomAsserter
(
SIZE
,
Double
.
MAX_VALUE
,
0
d
)
});
// Bounded
for
(
int
b
:
BOUNDS
)
{
for
(
int
o
:
ORIGINS
)
{
final
double
origin
=
o
;
final
double
bound
=
b
;
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofDoubleSupplier
(
String
.
format
(
"new SplittableRandom().doubles(%f, %f).limit(%d)"
,
origin
,
bound
,
SIZE
),
()
->
new
SplittableRandom
().
doubles
(
origin
,
bound
).
limit
(
SIZE
)),
randomAsserter
(
SIZE
,
origin
,
bound
)
});
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofDoubleSupplier
(
String
.
format
(
"new SplittableRandom().doubles(%d, %f, %f)"
,
SIZE
,
origin
,
bound
),
()
->
new
SplittableRandom
().
doubles
(
SIZE
,
origin
,
bound
)),
randomAsserter
(
SIZE
,
origin
,
bound
)
});
if
(
origin
==
0
)
{
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofDoubleSupplier
(
String
.
format
(
"new RandomBoxedSpliterator(0, %d, sr -> sr.nextDouble(%f))"
,
SIZE
,
bound
),
()
->
rbsf
.
apply
(
sr
->
sr
.
nextDouble
(
bound
))),
randomAsserter
(
SIZE
,
origin
,
bound
)
});
}
data
.
add
(
new
Object
[]{
TestData
.
Factory
.
ofDoubleSupplier
(
String
.
format
(
"new RandomBoxedSpliterator(0, %d, sr -> sr.nextDouble(%f, %f))"
,
SIZE
,
origin
,
bound
),
()
->
rbsf
.
apply
(
sr
->
sr
.
nextDouble
(
origin
,
bound
))),
randomAsserter
(
SIZE
,
origin
,
bound
)
});
}
}
return
data
.
toArray
(
new
Object
[
0
][]);
}
@Test
(
dataProvider
=
"doubles"
)
public
void
testDoubles
(
TestData
.
OfDouble
data
,
ResultAsserter
<
Iterable
<
Double
>>
ra
)
{
withData
(
data
).
stream
(
s
->
s
).
without
(
DoubleStreamTestScenario
.
PAR_STREAM_TO_ARRAY_CLEAR_SIZED
).
resultAsserter
(
ra
).
exercise
();
}
}
test/java/util/zip/TestExtraTime.java
浏览文件 @
f9ad02d9
...
...
@@ -23,7 +23,7 @@
/**
* @test
* @bug 4759491 6303183 7012868 8015666
* @bug 4759491 6303183 7012868 8015666
8023713
* @summary Test ZOS and ZIS timestamp in extra field correctly
*/
...
...
@@ -32,6 +32,7 @@ import java.nio.file.Files;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
import
java.nio.file.attribute.FileTime
;
import
java.util.Arrays
;
import
java.util.TimeZone
;
import
java.util.concurrent.TimeUnit
;
import
java.util.zip.ZipEntry
;
...
...
@@ -52,24 +53,26 @@ public class TestExtraTime {
FileTime
ctime
=
FileTime
.
from
(
time
-
300000
,
TimeUnit
.
MILLISECONDS
);
TimeZone
tz
=
TimeZone
.
getTimeZone
(
"Asia/Shanghai"
);
test
(
mtime
,
null
,
null
,
null
);
for
(
byte
[]
extra
:
new
byte
[][]
{
null
,
new
byte
[]
{
1
,
2
,
3
}})
{
test
(
mtime
,
null
,
null
,
null
,
extra
);
// ms-dos 1980 epoch problem
test
(
FileTime
.
from
(
10
,
TimeUnit
.
MILLISECONDS
),
null
,
null
,
null
);
test
(
FileTime
.
from
(
10
,
TimeUnit
.
MILLISECONDS
),
null
,
null
,
null
,
extra
);
// non-default tz
test
(
mtime
,
null
,
null
,
tz
);
test
(
mtime
,
null
,
null
,
tz
,
extra
);
test
(
mtime
,
atime
,
null
,
null
);
test
(
mtime
,
null
,
ctime
,
null
);
test
(
mtime
,
atime
,
ctime
,
null
);
test
(
mtime
,
atime
,
null
,
null
,
extra
);
test
(
mtime
,
null
,
ctime
,
null
,
extra
);
test
(
mtime
,
atime
,
ctime
,
null
,
extra
);
test
(
mtime
,
atime
,
null
,
tz
);
test
(
mtime
,
null
,
ctime
,
tz
);
test
(
mtime
,
atime
,
ctime
,
tz
);
test
(
mtime
,
atime
,
null
,
tz
,
extra
);
test
(
mtime
,
null
,
ctime
,
tz
,
extra
);
test
(
mtime
,
atime
,
ctime
,
tz
,
extra
);
}
}
}
static
void
test
(
FileTime
mtime
,
FileTime
atime
,
FileTime
ctime
,
TimeZone
tz
)
throws
Throwable
{
TimeZone
tz
,
byte
[]
extra
)
throws
Throwable
{
System
.
out
.
printf
(
"--------------------%nTesting: [%s]/[%s]/[%s]%n"
,
mtime
,
atime
,
ctime
);
TimeZone
tz0
=
TimeZone
.
getDefault
();
...
...
@@ -78,8 +81,8 @@ public class TestExtraTime {
}
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
();
ZipOutputStream
zos
=
new
ZipOutputStream
(
baos
);
ZipEntry
ze
=
new
ZipEntry
(
"TestExtr
e
Time.java"
);
ZipEntry
ze
=
new
ZipEntry
(
"TestExtr
a
Time.java"
);
ze
.
setExtra
(
extra
);
ze
.
setLastModifiedTime
(
mtime
);
if
(
atime
!=
null
)
ze
.
setLastAccessTime
(
atime
);
...
...
@@ -87,6 +90,14 @@ public class TestExtraTime {
ze
.
setCreationTime
(
ctime
);
zos
.
putNextEntry
(
ze
);
zos
.
write
(
new
byte
[]
{
1
,
2
,
3
,
4
});
// append an extra entry to help check if the length and data
// of the extra field are being correctly written (in previous
// entry).
if
(
extra
!=
null
)
{
ze
=
new
ZipEntry
(
"TestExtraEntry"
);
zos
.
putNextEntry
(
ze
);
}
zos
.
close
();
if
(
tz
!=
null
)
{
TimeZone
.
setDefault
(
tz0
);
...
...
@@ -96,23 +107,23 @@ public class TestExtraTime {
new
ByteArrayInputStream
(
baos
.
toByteArray
()));
ze
=
zis
.
getNextEntry
();
zis
.
close
();
check
(
mtime
,
atime
,
ctime
,
ze
);
check
(
mtime
,
atime
,
ctime
,
ze
,
extra
);
// ZipFile
Path
zpath
=
Paths
.
get
(
System
.
getProperty
(
"test.dir"
,
"."
),
"TestExtraTim
p
.zip"
);
"TestExtraTim
e
.zip"
);
Files
.
copy
(
new
ByteArrayInputStream
(
baos
.
toByteArray
()),
zpath
);
ZipFile
zf
=
new
ZipFile
(
zpath
.
toFile
());
ze
=
zf
.
getEntry
(
"TestExtr
e
Time.java"
);
ze
=
zf
.
getEntry
(
"TestExtr
a
Time.java"
);
// ZipFile read entry from cen, which does not have a/ctime,
// for now.
check
(
mtime
,
null
,
null
,
ze
);
check
(
mtime
,
null
,
null
,
ze
,
extra
);
zf
.
close
();
Files
.
delete
(
zpath
);
}
static
void
check
(
FileTime
mtime
,
FileTime
atime
,
FileTime
ctime
,
ZipEntry
ze
)
{
ZipEntry
ze
,
byte
[]
extra
)
{
/*
System.out.printf(" mtime [%tc]: [%tc]/[%tc]%n",
mtime.to(TimeUnit.MILLISECONDS),
...
...
@@ -130,5 +141,17 @@ public class TestExtraTime {
ctime
.
to
(
TimeUnit
.
SECONDS
)
!=
ze
.
getCreationTime
().
to
(
TimeUnit
.
SECONDS
))
throw
new
RuntimeException
(
"Timestamp: storing ctime failed!"
);
if
(
extra
!=
null
)
{
// if extra data exists, the current implementation put it at
// the end of the extra data array (implementation detail)
byte
[]
extra1
=
ze
.
getExtra
();
if
(
extra1
==
null
||
extra1
.
length
<
extra
.
length
||
!
Arrays
.
equals
(
Arrays
.
copyOfRange
(
extra1
,
extra1
.
length
-
extra
.
length
,
extra1
.
length
),
extra
))
{
throw
new
RuntimeException
(
"Timestamp: storing extra field failed!"
);
}
}
}
}
test/sun/security/krb5/auto/KPEquals.java
0 → 100644
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8015669
* @summary KerberosPrincipal::equals should ignore name-type
* @compile -XDignore.symbol.file KPEquals.java
* @run main/othervm KPEquals
*/
import
sun.security.jgss.GSSUtil
;
import
javax.security.auth.kerberos.KerberosKey
;
import
javax.security.auth.kerberos.KerberosPrincipal
;
import
javax.security.auth.kerberos.KeyTab
;
public
class
KPEquals
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
new
OneKDC
(
null
).
writeJAASConf
();
Context
c
=
Context
.
fromJAAS
(
"client"
);
Context
s
=
Context
.
fromThinAir
();
KerberosPrincipal
kp
=
new
KerberosPrincipal
(
OneKDC
.
SERVER
+
"@"
+
OneKDC
.
REALM
,
KerberosPrincipal
.
KRB_NT_SRV_INST
);
s
.
s
().
getPrincipals
().
add
(
kp
);
for
(
KerberosKey
k:
KeyTab
.
getInstance
(
kp
).
getKeys
(
kp
))
{
s
.
s
().
getPrivateCredentials
().
add
(
k
);
}
c
.
startAsClient
(
OneKDC
.
SERVER
,
GSSUtil
.
GSS_KRB5_MECH_OID
);
s
.
startAsServer
(
OneKDC
.
SERVER
,
GSSUtil
.
GSS_KRB5_MECH_OID
);
Context
.
handshake
(
c
,
s
);
}
}
test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2001, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -21,14 +21,16 @@
* questions.
*/
//
// SunJSSE does not support dynamic system properties, no way to re-use
// system properties in samevm/agentvm mode.
//
/*
* @test
* @bug 4366807
* @summary Need new APIs to get/set session timeout and session cache size.
* @run main/othervm SessionCacheSizeTests
*
* SunJSSE does not support dynamic system properties, no way to re-use
* system properties in samevm/agentvm mode.
*/
import
java.io.*
;
...
...
@@ -113,7 +115,9 @@ public class SessionCacheSizeTests {
/*
* Signal Client, we're ready for his connect.
*/
if
(
createdPorts
==
serverPorts
.
length
)
{
serverReady
=
true
;
}
int
read
=
0
;
int
nConnections
=
0
;
/*
...
...
@@ -310,7 +314,6 @@ public class SessionCacheSizeTests {
* Fork off the other side, then do your work.
*/
SessionCacheSizeTests
()
throws
Exception
{
/*
* create the SSLServerSocket and SSLSocket factories
*/
...
...
@@ -323,10 +326,12 @@ public class SessionCacheSizeTests {
int
serverConns
=
MAX_ACTIVE_CONNECTIONS
/
(
serverPorts
.
length
);
int
remainingConns
=
MAX_ACTIVE_CONNECTIONS
%
(
serverPorts
.
length
);
Exception
startException
=
null
;
try
{
if
(
separateServerThread
)
{
for
(
int
i
=
0
;
i
<
serverPorts
.
length
;
i
++)
{
// distribute remaining connections among the
available ports
// distribute remaining connections among the
//
available ports
if
(
i
<
remainingConns
)
startServer
(
serverPorts
[
i
],
(
serverConns
+
1
),
true
);
else
...
...
@@ -342,27 +347,66 @@ public class SessionCacheSizeTests {
startServer
(
serverPorts
[
i
],
serverConns
,
false
);
}
}
}
catch
(
Exception
e
)
{
startException
=
e
;
}
/*
* Wait for other side to close down.
*/
if
(
separateServerThread
)
{
if
(
serverThread
!=
null
)
{
serverThread
.
join
();
}
}
else
{
if
(
clientThread
!=
null
)
{
clientThread
.
join
();
}
}
/*
* When we get here, the test is pretty much over.
*
* If the main thread excepted, that propagates back
* immediately. If the other thread threw an exception, we
* should report back.
*/
if
(
serverException
!=
null
)
throw
serverException
;
if
(
clientException
!=
null
)
throw
clientException
;
Exception
local
;
Exception
remote
;
if
(
separateServerThread
)
{
remote
=
serverException
;
local
=
clientException
;
}
else
{
remote
=
clientException
;
local
=
serverException
;
}
Exception
exception
=
null
;
/*
* Check various exception conditions.
*/
if
((
local
!=
null
)
&&
(
remote
!=
null
))
{
// If both failed, return the curthread's exception.
local
.
initCause
(
remote
);
exception
=
local
;
}
else
if
(
local
!=
null
)
{
exception
=
local
;
}
else
if
(
remote
!=
null
)
{
exception
=
remote
;
}
else
if
(
startException
!=
null
)
{
exception
=
startException
;
}
/*
* If there was an exception *AND* a startException,
* output it.
*/
if
(
exception
!=
null
)
{
if
(
exception
!=
startException
&&
startException
!=
null
)
{
exception
.
addSuppressed
(
startException
);
}
throw
exception
;
}
// Fall-through: no exception to throw!
}
void
startServer
(
final
int
port
,
final
int
nConns
,
...
...
@@ -387,7 +431,13 @@ public class SessionCacheSizeTests {
};
serverThread
.
start
();
}
else
{
try
{
doServerSide
(
port
,
nConns
);
}
catch
(
Exception
e
)
{
serverException
=
e
;
}
finally
{
serverReady
=
true
;
}
}
}
...
...
@@ -409,7 +459,11 @@ public class SessionCacheSizeTests {
};
clientThread
.
start
();
}
else
{
try
{
doClientSide
();
}
catch
(
Exception
e
)
{
clientException
=
e
;
}
}
}
}
test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java
浏览文件 @
f9ad02d9
/*
* Copyright (c) 2001, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 201
3
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -21,14 +21,14 @@
* questions.
*/
// SunJSSE does not support dynamic system properties, no way to re-use
// system properties in samevm/agentvm mode.
/*
* @test
* @bug 4366807
* @summary Need new APIs to get/set session timeout and session cache size.
* @run main/othervm SessionTimeOutTests
*
* SunJSSE does not support dynamic system properties, no way to re-use
* system properties in samevm/agentvm mode.
*/
import
java.io.*
;
...
...
@@ -348,9 +348,12 @@ public class SessionTimeOutTests {
int
serverConns
=
MAX_ACTIVE_CONNECTIONS
/
(
serverPorts
.
length
);
int
remainingConns
=
MAX_ACTIVE_CONNECTIONS
%
(
serverPorts
.
length
);
Exception
startException
=
null
;
try
{
if
(
separateServerThread
)
{
for
(
int
i
=
0
;
i
<
serverPorts
.
length
;
i
++)
{
// distribute remaining connections among the available ports
// distribute remaining connections among the
// vailable ports
if
(
i
<
remainingConns
)
startServer
(
serverPorts
[
i
],
(
serverConns
+
1
),
true
);
else
...
...
@@ -366,27 +369,67 @@ public class SessionTimeOutTests {
startServer
(
serverPorts
[
i
],
serverConns
,
false
);
}
}
}
catch
(
Exception
e
)
{
startException
=
e
;
}
/*
* Wait for other side to close down.
*/
if
(
separateServerThread
)
{
if
(
serverThread
!=
null
)
{
serverThread
.
join
();
}
}
else
{
if
(
clientThread
!=
null
)
{
clientThread
.
join
();
}
}
/*
* When we get here, the test is pretty much over.
*
* If the main thread excepted, that propagates back
* immediately. If the other thread threw an exception, we
* should report back.
* Which side threw the error?
*/
Exception
local
;
Exception
remote
;
if
(
separateServerThread
)
{
remote
=
serverException
;
local
=
clientException
;
}
else
{
remote
=
clientException
;
local
=
serverException
;
}
Exception
exception
=
null
;
/*
* Check various exception conditions.
*/
if
(
serverException
!=
null
)
throw
serverException
;
if
(
clientException
!=
null
)
throw
clientException
;
if
((
local
!=
null
)
&&
(
remote
!=
null
))
{
// If both failed, return the curthread's exception.
local
.
initCause
(
remote
);
exception
=
local
;
}
else
if
(
local
!=
null
)
{
exception
=
local
;
}
else
if
(
remote
!=
null
)
{
exception
=
remote
;
}
else
if
(
startException
!=
null
)
{
exception
=
startException
;
}
/*
* If there was an exception *AND* a startException,
* output it.
*/
if
(
exception
!=
null
)
{
if
(
exception
!=
startException
&&
startException
!=
null
)
{
exception
.
addSuppressed
(
startException
);
}
throw
exception
;
}
// Fall-through: no exception to throw!
}
void
startServer
(
final
int
port
,
final
int
nConns
,
...
...
@@ -411,7 +454,13 @@ public class SessionTimeOutTests {
};
serverThread
.
start
();
}
else
{
try
{
doServerSide
(
port
,
nConns
);
}
catch
(
Exception
e
)
{
serverException
=
e
;
}
finally
{
serverReady
=
0
;
}
}
}
...
...
@@ -433,7 +482,11 @@ public class SessionTimeOutTests {
};
clientThread
.
start
();
}
else
{
try
{
doClientSide
();
}
catch
(
Exception
e
)
{
clientException
=
e
;
}
}
}
}
test/sun/security/ssl/templates/SSLSocketTemplate.java
浏览文件 @
f9ad02d9
...
...
@@ -243,7 +243,7 @@ public class SSLSocketTemplate {
* output it.
*/
if
(
exception
!=
null
)
{
if
(
exception
!=
startException
)
{
if
(
exception
!=
startException
&&
startException
!=
null
)
{
exception
.
addSuppressed
(
startException
);
}
throw
exception
;
...
...
test/sun/security/tools/jarsigner/jvindex.sh
0 → 100644
浏览文件 @
f9ad02d9
#
# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# @test
# @bug 8022761
# @summary regression: SecurityException is NOT thrown while trying to pack a wrongly signed Indexed Jar file
#
if
[
"
${
TESTJAVA
}
"
=
""
]
;
then
JAVAC_CMD
=
`
which javac
`
TESTJAVA
=
`
dirname
$JAVAC_CMD
`
/..
fi
# set platform-dependent variables
OS
=
`
uname
-s
`
case
"
$OS
"
in
Windows_
*
)
FS
=
"
\\
"
;;
*
)
FS
=
"/"
;;
esac
F
=
abcde
KS
=
jvindex.jks
JFILE
=
jvindex.jar
KT
=
"
$TESTJAVA
${
FS
}
bin
${
FS
}
keytool -storepass changeit -keypass changeit
\
-keystore
$KS
"
JAR
=
$TESTJAVA
${
FS
}
bin
${
FS
}
jar
JARSIGNER
=
"
$TESTJAVA
${
FS
}
bin
${
FS
}
jarsigner -keystore
$KS
-storepass changeit"
rm
$F
$KS
$JFILE
2> /dev/null
echo
12345
>
$F
$JAR
cvf
$JFILE
$F
ERR
=
""
$KT
-alias
a
-dname
CN
=
a
-genkey
-validity
300
||
ERR
=
"
$ERR
1"
$JARSIGNER
$JFILE
a
||
ERR
=
"
$ERR
2"
$JAR
i
$JFILE
# Make sure the $F line has "sm" (signed and in manifest)
$JARSIGNER
-verify
-verbose
$JFILE
|
grep
$F
|
grep
sm
||
ERR
=
"
$ERR
3"
if
[
"
$ERR
"
=
""
]
;
then
exit
0
else
echo
"ERR is
$ERR
"
exit
1
fi
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录