Java 17 添加了新的RandomGenerator接口。然而,似乎所有新的实现都不是线程安全的。在多线程情况下使用新接口的推荐方法是在生成新线程时使用原始线程SplittableRandom并进行调用。split但是,在某些情况下,您无法控制生成新线程的代码部分,而只需在多个线程之间共享一个实例。
我可以使用Random,但这会因为所有同步而导致争用。也可以使用ThreadLocalRandom,但我不愿意这样做,因为这个类现在被认为是“遗留的RandomGenerator”,并且因为这不会给我一个没有全部样板负载的线程安全实现:
new RandomGenerator() {
@Override
public int nextInt() {
return ThreadLocalRandom.current().nextInt();
}
@Override
public long nextLong() {
return ThreadLocalRandom.current().nextLong();
}
...
}
Run Code Online (Sandbox Code Playgroud)
对我来说,这似乎是新 API 中相当基本的差距,但我可能会遗漏一些东西。获得线程安全实现的惯用 Java 17 方法是什么RandomGenerator?
我使用的是 Windows 操作系统,因此 Font(java.awt) 类对象创建没有问题。但我的测试环境是linux。所以我得到了 NULL POINTER 异常。
Cannot load from short array because "sun.awt.FontConfiguration.head" is null
Run Code Online (Sandbox Code Playgroud)
经过搜索,我发现linux上的usr/share目录下应该有fonts文件夹。所以有人可以建议。我是否必须将字体复制到该目录或有其他方法来安装?
我正在将一个简单的类转换为一条记录,如下所示:
public class Mine {
private final String name;
public Mine(String name) {
this.name = name == null ? "a" : name;
}
}
Run Code Online (Sandbox Code Playgroud)
本能地,我是这样写的:
public record Mine(String name) {
public Mine {
this.name = name == null ? "a" : name;
}
}
Run Code Online (Sandbox Code Playgroud)
无法编译:cannot assign a value to final variable name.
我有点困惑,因为这个紧凑的构造函数有效:
public Mine {
name = name == null ? "a" : name;
}
Run Code Online (Sandbox Code Playgroud)
我无法真正理解发生了什么,所以我决定查看字节码:
0: aload_0
1: invokespecial #1 // Method java/lang/Record."<init>":()V
4: aload_1
5: …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Spring Boot 3、Java 17、Open Api 3 查看 Swagger 页面。
我一定做错了什么,但是什么?是不是有什么不兼容的地方?
在 http://localhost:8080/v3/api-docs/ 或 http://localhost:8080/swagger-ui 我得到Whitelabel错误页面。
我正在从 Spring Boot 2.5 迁移,但为了确保我没有忘记删除导致此错误的某些内容,我从此处复制了一个教程https://www.techgeeknext.com/spring-boot/spring-boot- swagger3-example(我在这篇文章的末尾写了它)。
虽然运行了,但控制台中出现错误:
ERROR Class 'org.springframework.core.io.support.PathMatchingResourcePatternResolver' could not be processed by org.zeroturnaround.javarebel.integration.spring.core.cbp.PathMatchingResourcePatternResolverCBP@jdk.internal.loader.ClassLoaders$AppClassLoader@7a46a697: org.zeroturnaround.bundled.javassist.NotFoundException: retrieveMatchingFiles(..) is not found in org.springframework.core.io.support.PathMatchingResourcePatternResolver
at org.zeroturnaround.bundled.javassist.CtClassType.getDeclaredMethod(SourceFile:1356)
at org.zeroturnaround.javarebel.integration.spring.core.cbp.PathMatchingResourcePatternResolverCBP.registerScannedDirs(PathMatchingResourcePatternResolverCBP.java:255)
at org.zeroturnaround.javarebel.integration.spring.core.cbp.PathMatchingResourcePatternResolverCBP.process(PathMatchingResourcePatternResolverCBP.java:41)
at org.zeroturnaround.javarebel.integration.support.JavassistClassBytecodeProcessor.process(SourceFile:137)
at org.zeroturnaround.javarebel.integration.support.CacheAwareJavassistClassBytecodeProcessor.process(SourceFile:34)
at org.zeroturnaround.javarebel.integration.support.JavassistClassBytecodeProcessor.process(SourceFile:83)
at com.zeroturnaround.javarebel.yg.a(SourceFile:413)
at com.zeroturnaround.javarebel.yg.a(SourceFile:340)
at com.zeroturnaround.javarebel.SDKIntegrationImpl.runBytecodeProcessors(SourceFile:44)
at com.zeroturnaround.javarebel.vk.transform(SourceFile:140)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:43009)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
at org.springframework.core.io.support.ResourceArrayPropertyEditor.<init>(ResourceArrayPropertyEditor.java:77)
at …Run Code Online (Sandbox Code Playgroud) 我有一个非常简单的场景。以下方法尝试访问锁,等待 1 秒并最终释放锁。
private final Lock lock = new ReentrantLock();
public void lockAndWait() {
logger.info("I {} am here", Thread.currentThread().getName());
lock.lock();
try {
logger.info("I {} got the lock", Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} finally {
lock.unlock();
}
}
Run Code Online (Sandbox Code Playgroud)
我正在运行以下测试:
@Test
public void lockTest() {
for (int i = 0; i < 10; i++) {
new Thread(() -> lockAndWait()).start();
}
}
Run Code Online (Sandbox Code Playgroud)
我得到以下日志输出:
12-10-2023 17:11:04 [Thread-2 ] INFO I Thread-2 am here
12-10-2023 17:11:04 …Run Code Online (Sandbox Code Playgroud) 我的服务器和本地环境之间的时区转换遇到问题。我有一个实体帐户,其字段 accountCreationDate 为 OffsetDateTime。详细信息如下:
在我的代码中,我尝试在服务器和本地环境之间转换时间戳:
if (accountRequest.getAccountCreationDate() != null) {
Instant instant = Instant.ofEpochMilli(accountRequest.getAccountCreationDate());
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneOffset.UTC);
ZonedDateTime cetDateTime = zonedDateTime.withZoneSameInstant(ZoneOffset.ofHours(1));
OffsetDateTime offsetDateTime = cetDateTime.toOffsetDateTime();
requestTransformer.setAccountDateCreation(offsetDateTime);
}
Run Code Online (Sandbox Code Playgroud)
响应变压器:
if (pamUserAccount.getAccountDateCreation() != null) {
OffsetDateTime cetDateTime = pamUserAccount.getAccountDateCreation();
LocalDateTime localDateTime = cetDateTime.toLocalDate().atStartOfDay();
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneOffset.ofHours(1)); // GMT+01:00
long epochMillis = zonedDateTime.withZoneSameInstant(ZoneOffset.UTC)
.toInstant()
.toEpochMilli();
response.setAccountDateCreation(epochMillis);
Run Code Online (Sandbox Code Playgroud)
本地工作正常,时间戳为 1542754800000,转换为 2018-11-21T00:00+01:00 OffsetDateTime 并返回结果。但是,在服务器上,我什么也没有得到。我希望收到同一行数据。对这里可能出了什么问题有什么见解吗?
我也检查了一下:
pamUserAccount.getAccountDateCreation();
Run Code Online (Sandbox Code Playgroud)
本地我得到:2018-11-21T01:00+01:00
在服务器中我得到:2018-11-21T00:00Z
在 Java 11 中,时钟系统使用毫秒精度,但显然在 Java 13 及更高版本中,它使用微秒精度,这导致我的测试失败。例如,OffsetDateTime.now()当我从数据库“2021-12-10T10:58:05.309595+01:00”读取此日期时,给我这个日期“2021-12-10T10:58:05.309594500+01:00”。我正在寻找一种方法,可以以它们应该相等的方式格式化第一个日期。我确实希望将其设置为 OffsetDateTime 类型而不是字符串。
更新:我意识到这个问题是在我将java版本从11升级到17时出现的,而不是在本地,当gitlab运行测试时我遇到了这个问题。
这是测试:
@Test
fun `can store, find and delete a failed-message`() {
// given: a failed-message
val failedMessage = FailedMessage(
failedMessageId = FailedMessageId("the-subcription", "the-message-id"),
messageAttributes = mapOf("one" to "een", "two" to "twee"),
messagePayload = "message-payload",
exception = "exception",
dateTime = OffsetDateTime.now(),
stackTrace = "stackey tracey"
)
failedMessageRepository.store(failedMessage)
assertEquals(failedMessage, failedMessageRepository.find(failedMessage.failedMessageId))
}
Run Code Online (Sandbox Code Playgroud)
由于日期时间不相等,该测试失败。这是日志:
<FailedMessage(failedMessageId=the-subcription-the-message-id, messageAttributes={one=een, two=twee}, messagePayload=message-payload, exception=exception, dateTime=2021-12-10T10:58:05.309594500+01:00, stackTrace=stackey tracey)>
but was:
<FailedMessage(failedMessageId=the-subcription-the-message-id, messageAttributes={one=een, two=twee}, messagePayload=message-payload, exception=exception, dateTime=2021-12-10T10:58:05.309595+01:00, stackTrace=stackey tracey)> …Run Code Online (Sandbox Code Playgroud) 之前关于在 Java 中从字节数组读取整数的讨论,重点关注的是四个字节的场景。我的情况略有不同:
二十亿字节的固定数组。
输入:该数组的随机偏移量。(尽管希望足够的非随机性以获得相当高的缓存命中率。)
该操作会频繁发生,因此需要尽可能快地运行。理想的情况是存在一种 JIT 编译器可以识别的习惯用法并将其编译为未对齐的加载指令(如果 CPU 支持这种习惯)。(每个主流 CPU 都会在每次内存访问中为未对齐的支持付费,即使在不使用它的典型情况下也是如此。不妨利用它,这一次它会很有用。)
执行此操作最快的方法是什么?显然我可以手动编写读取移位循环,但是有没有更快的习惯用法?或者,如果要手动完成,哪种变体会生成最快的代码?
我使用的是 OpenJDK 17,如果这很重要的话。
我有一个主要方法,用于创建自定义类加载器并用它实例化一个名为 Test 的类。
public class App {
public static void main(String[] args) throws Exception {
try {
Class.forName("com.mycompany.app2.Test2"); // We ensure that Test2 is not part of current classpath
System.err.println("Should have thrown ClassNotFound");
System.exit(1);
} catch (ClassNotFoundException e) {
// ignore
}
String jar = "C:\\experiments\\classloader-test2\\target\\classloader-test2-1.0-SNAPSHOT.jar"; // Contains Test2
URL[] classPaths = new URL[] { new File(jar).toURI().toURL() };
ClassLoader classLoader = new URLClassLoader(classPaths, App.class.getClassLoader());
Thread.currentThread().setContextClassLoader(classLoader);
Class.forName("com.mycompany.app2.Test2", true, classLoader); // Check that custom class loader can find the wanted class
Test …Run Code Online (Sandbox Code Playgroud) java classloader urlclassloader classnotfoundexception java-17
我正在尝试将在 java 8 上运行的 spring boot 2.3 应用程序迁移到 spring boot 3 java 17。问题出在存储库中。
其查询方法如下:
@Query(value = "SELECT ca FROM CorporateActionsV2 ca WHERE ( ca.dividendAmount, TO_CHAR(TO_DATE(ca.effectiveDate) - 5,'IYYY'), TO_CHAR(TO_DATE(ca.effectiveDate) - 5,'IW'), ca.tickerSerial) IN (SELECT c.dividendAmount, TO_CHAR(TO_DATE(c.effectiveDate) - 5,'IYYY'), TO_CHAR(TO_DATE(c.effectiveDate) - 5,'IW'), c.tickerSerial FROM CorporateActionsV2 c WHERE c.dividendAmount IS NOT NULL AND c.eventLabel = 'Dividend' AND c.actionStatus != 'Deleted'" +
" GROUP BY c.dividendAmount, TO_CHAR(TO_DATE(c.effectiveDate) - 5,'IYYY'), TO_CHAR(TO_DATE(c.effectiveDate) - 5,'IW'), c.tickerSerial HAVING COUNT(*) > 1 )")
List<CorporateActionsV2> getDuplicateActions();
Run Code Online (Sandbox Code Playgroud)
该实体CorporateActionsV2具有以下日期结构:
@Temporal(TemporalType.DATE) …Run Code Online (Sandbox Code Playgroud) java-17 ×10
java ×8
spring-boot ×2
arrays ×1
bytecode ×1
classloader ×1
concurrency ×1
database ×1
datetime ×1
fontconfig ×1
fonts ×1
java-11 ×1
linux ×1
openapi ×1
oracle ×1
performance ×1
random ×1
record ×1
sleep ×1
springdoc ×1