我们知道,默认情况下迭代并发集合不是线程安全的,所以不能使用:
Set<E> set = Collections.synchronizedSet(new HashSet<>());
//fill with data
for (E e : set) {
process(e);
}
Run Code Online (Sandbox Code Playgroud)
这是因为在迭代期间可能会添加数据,因为没有排他锁set.
这在javadoc中描述Collections.synchronizedSet:
public static Set synchronizedSet(Set s)
返回由指定集支持的同步(线程安全)集.为了保证串行访问,必须通过返回的集完成对后备集的所有访问.
当迭代它时,用户必须手动同步返回的集合:
Set s = Collections.synchronizedSet(new HashSet());
...
synchronized (s) { Iterator i = s.iterator(); // Must be in the synchronized block while (i.hasNext()) foo(i.next()); }不遵循此建议可能会导致非确定性行为.
然而,这并不适用于Set.forEach,它继承了默认的方法forEach从Iterable.forEach.
现在我查看了源代码,在这里我们可以看到我们有以下结构:
Collections.synchronizedSet().我们得到一个:
public static <T> Set<T> synchronizedSet(Set<T> s) {
return new SynchronizedSet<>(s); …Run Code Online (Sandbox Code Playgroud)假设我有一些异步计算,例如:
CompletableFuture
.supplyAsync(() -> createFoo())
.thenAccept(foo -> doStuffWithFoo(foo));
Run Code Online (Sandbox Code Playgroud)
如果异步供应商根据某些指定的超时超时,是否有一种很好的方法为foo提供默认值?理想情况下,此类功能也会尝试取消运行缓慢的供应商.例如,是否存在类似于以下假设代码的标准库功能:
CompletableFuture
.supplyAsync(() -> createFoo())
.acceptEither(
CompletableFuture.completedAfter(50, TimeUnit.MILLISECONDS, DEFAULT_FOO),
foo -> doStuffWithFoo(foo));
Run Code Online (Sandbox Code Playgroud)
或者甚至更好:
CompletableFuture
.supplyAsync(() -> createFoo())
.withDefault(DEFAULT_FOO, 50, TimeUnit.MILLISECONDS)
.thenAccept(foo -> doStuffWithFoo(foo));
Run Code Online (Sandbox Code Playgroud)
我知道get(timeout, unit),但我想知道是否有一种更好的标准方式,以异步和反应方式应用超时,如上面的代码所示.
编辑:这是一个受Java 8启发的解决方案:在lambda表达式中强制检查异常处理.为什么强制,不是可选的?,但不幸的是它阻止了一个线程.如果我们依赖createFoo()来异步检查超时并抛出自己的超时异常,它可以在不阻塞线程的情况下工作,但会给供应商的创建者带来更多负担,并且仍然会产生创建异常的成本(可以没有"快速投掷"而昂贵
static <T> Supplier<T> wrapped(Callable<T> callable) {
return () -> {
try {
return callable.call();
} catch (RuntimeException e1) {
throw e1;
} catch (Throwable e2) {
throw new RuntimeException(e2);
}
};
}
CompletableFuture
.supplyAsync(wrapped(() -> CompletableFuture.supplyAsync(() -> createFoo()).get(50, …Run Code Online (Sandbox Code Playgroud) 我注意到一个奇怪的结构ConcurrentHashMap的compute和computeIfAbsent方法:
Node<K,V> r = new ReservationNode<K,V>();
synchronized (r) {
//...
}
Run Code Online (Sandbox Code Playgroud)
考虑到JIT最有可能将其视为无操作,本地对象同步的重点是什么?
我有一个流如:
Arrays.stream(new String[]{"matt", "jason", "michael"});
Run Code Online (Sandbox Code Playgroud)
我想删除以相同字母开头的名称,以便只留下以该字母开头的一个名称(无关紧要).
我试图了解该distinct()方法的工作原理.我在文档中读到它基于对象的"等于"方法.但是,当我尝试包装String时,我注意到从不调用equals方法,也没有删除任何内容.这里有什么我想念的吗?
包装类:
static class Wrp {
String test;
Wrp(String s){
this.test = s;
}
@Override
public boolean equals(Object other){
return this.test.charAt(0) == ((Wrp) other).test.charAt(0);
}
}
Run Code Online (Sandbox Code Playgroud)
还有一些简单的代码:
public static void main(String[] args) {
Arrays.stream(new String[]{"matt", "jason", "michael"})
.map(Wrp::new)
.distinct()
.map(wrp -> wrp.test)
.forEach(System.out::println);
}
Run Code Online (Sandbox Code Playgroud) 假设我有一串字符串.
final Stream<String> stream = ...;
Run Code Online (Sandbox Code Playgroud)
我想在修剪后过滤掉每个空字符串.
stream
.filter(Objects::nonNull)
.map(String::trim)
.filter(v -> !v.isEmpty());
Run Code Online (Sandbox Code Playgroud)
有没有办法应用Predicate#negate()替换v -> !v.isEmpty()部分?
.filter(((Predicate) String::isEmpty).negate()) // not compile
Run Code Online (Sandbox Code Playgroud) 我创建了简单的演示:
public static void main(String[] args) {
List<String> list2 = Arrays.asList("adf", "bcd", "abc", "hgr", "jyt", "edr", "biu");
String collect = list2.stream().collect(String::new, (res, elem) -> {
res=res.concat(" ").concat(elem);
// System.out.printf("res=%s, elem=%s\n", res.isEmpty(), elem);
}, (res1, res2) -> {
System.out.printf("res1=%s, res2=%s\n", res1, res2);
});
System.out.println("collect=" + collect);
}
Run Code Online (Sandbox Code Playgroud)
问题是BiConsumer combiner部分collect根本没有运行.
如果我使用parallelStream()两个参数res1并且res2等于供应商,它就会运行String::new.
如何combiner在collect方法中工作?
使用Java 8 StreamAPI,我想注册一个"完成钩子",类似于:
Stream<String> stream = Stream.of("a", "b", "c");
// additional filters / mappings that I don't control
stream.onComplete((Completion c) -> {
// This is what I'd like to do:
closeResources();
// This might also be useful:
Optional<Throwable> exception = c.exception();
exception.ifPresent(e -> throw new ExceptionWrapper(e));
});
Run Code Online (Sandbox Code Playgroud)
我为什么要那么做的原因是因为我想包装在一个资源Stream的API客户端,消费,我想的是Stream,一旦它被消耗自动清理资源.如果可能,那么客户可以致电:
Collected collectedInOneGo =
Utility.something()
.niceLookingSQLDSL()
.moreDSLFeatures()
.stream()
.filter(a -> true)
.map(c -> c)
.collect(collector);
Run Code Online (Sandbox Code Playgroud)
而不是目前所需要的:
try (Stream<X> meh = Utility.something()
.niceLookingSQLDSL()
.moreDSLFeatures()
.stream()) {
Collected collectedWithUglySyntacticDissonance = …Run Code Online (Sandbox Code Playgroud) 我刚刚被提示更新Java.它告诉我:
有人知道那个"助手"工具是做什么的吗?如果它是新的我可能不需要它.有没有办法选择退出?或者至少在安装之前知道它是什么?
请注意,我已经在"系统偏好设置"下的"Java控制面板"中选中了禁止赞助商优惠的选项.
另请注意,如果我未输入管理员密码,则不会安装更新.除了更新之外,它不是提供的,我可以接受或拒绝.
如果这是一个不好的问题或错误的地方,请评论.
这是一个后续行动.
我再次收到消息,并搜索了有关它的更多信息.我了解到更新过程已经包含在应用程序中.应用程序包装实际包,并提出其他软件.如果您选择退出,我猜它只是安装了Java更新.
"新助手工具"可能就是这个安装包装器,或者如果您不选择退出,可能还会提供其他软件.
如果您更喜欢安装干净的软件包,可以从安装程序中提取它.下载更新后,单击取消.然后转到~/Library/Application Support/Java(~/Library隐藏,所以使用Go> Go to folder ...).您可以看到所有过去的Java更新下载.选择最新版本.在文件夹中,您会看到一个应用程序和一个dmg.右键单击应用程序并选择Show Package Contents.在应用程序里面去Contents/Resources.你找到一个包裹JavaAppletPlugin.pkg.那是实际的包裹.双击它进行安装.它仍会询问您的姓名和密码,但这次是由OSX/macOS询问并用于安装该软件包而不是其他任何内容.
最新更新:今天更新失败.发生这种情况时,立即删除下载.在这种情况下,上述方法不起作用.
这开始看起来像博客.失败的下载是由于我的杀毒软件.当我禁用它时,它再次起作用.无论如何,我现在相信这个信息是无害的.操作系统X询问我是否同意运行Java安装程序.它不会尝试安装任何其他东西.我跑了.
guava库有它自己的Supplier,不扩展Java 8 Supplier.番石榴还为供应商提供缓存 - Suppliers#memoize.
是否有类似的东西,但对于Java 8供应商?
当我遇到一些令人惊讶的数字时,我正在使用jmh 1.21 比较JDK 8和11的性能:
Java version: 1.8.0_192, vendor: Oracle Corporation
Benchmark Mode Cnt Score Error Units
MyBenchmark.throwAndConsumeStacktrace avgt 25 21525.584 ± 58.957 ns/op
Java version: 9.0.4, vendor: Oracle Corporation
Benchmark Mode Cnt Score Error Units
MyBenchmark.throwAndConsumeStacktrace avgt 25 28243.899 ± 498.173 ns/op
Java version: 10.0.2, vendor: Oracle Corporation
Benchmark Mode Cnt Score Error Units
MyBenchmark.throwAndConsumeStacktrace avgt 25 28499.736 ± 215.837 ns/op
Java version: 11.0.1, vendor: Oracle Corporation
Benchmark Mode Cnt Score Error Units
MyBenchmark.throwAndConsumeStacktrace avgt 25 48535.766 ± 2175.753 …Run Code Online (Sandbox Code Playgroud) java-8 ×10
java ×9
java-stream ×3
auto-update ×1
collections ×1
guava ×1
install ×1
java-11 ×1
jmh ×1
lambda ×1
performance ×1
predicate ×1
string ×1
synchronized ×1