小编BKE*_*BKE的帖子

Java不使用所有可用的CPU

我有一个长期运行的计算,我需要执行一长串输入.计算是独立的,所以我想将它们分配给几个CPU.我使用的是Java 8.

代码的框架如下所示:

ExecutorService executorService = Executors.newFixedThreadPool(numThreads);

MyService myService = new MyService(executorService);

List<MyResult> results =
            myInputList.stream()
                     .map(myService::getResultFuture)
                     .map(CompletableFuture::join)
                     .collect(Collectors.toList());

executorService.shutdown();
Run Code Online (Sandbox Code Playgroud)

负责计算的主要功能如下:

CompletableFuture<MyResult> getResultFuture(MyInput input) {
    return CompletableFuture.supplyAsync(() -> longCalc(input), executor)))
}
Run Code Online (Sandbox Code Playgroud)

长时间运行的计算是无状态的,并且不执行任何IO.

我希望这段代码能够使用所有可用的CPU,但它不会发生.例如,在具有72个CPU和numThreads=72(或甚至例如numThreads=500)的机器上,CPU使用率最多为500-1000%,如htop所示:

HTOP

根据线程转储,许多计算线程都在等待,即:

"pool-1-thread-34" #55 prio=5 os_prio=0 tid=0x00007fe858597890 nid=0xd66 waiting on condition [0x00007fe7f9cdd000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x0000000381815f20> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

   Locked ownable synchronizers:
    - …
Run Code Online (Sandbox Code Playgroud)

java concurrency multithreading fork-join java-8

13
推荐指数
1
解决办法
500
查看次数

如何覆盖Kotlin生成的不必要的空检查?

考虑以下最小的Kotlin示例:

fun <U> someWrapper(supplier: () -> U): () -> (U) {
    return { supplier() }
}

fun foo(taskExecutor: TaskExecutor): Int {
    val future = CompletableFuture.supplyAsync(someWrapper {
        42
    }, taskExecutor::execute)
    return future.join()
}

@Test
public void shouldFoo() {
    assertThat(foo(), is(42));
}
Run Code Online (Sandbox Code Playgroud)

我在Jacoco中有分支覆盖规则,该规则对上面的代码失败,说someWrapper呼叫行未覆盖2个分支中的1个。不幸的是,对于我来说,排除所有someWrapper被调用的类不是一个选择。

查看反编译的Java代码:

public final int foo(TaskExecutor taskExecutor) {
    Object var10000 = WrappersKt.someWrapper((Function0)null.INSTANCE);
    if (var10000 != null) {
        Object var2 = var10000;
        var10000 = new Foo$sam$java_util_function_Supplier$0((Function0)var2);
    }

    Supplier var3 = (Supplier)var10000;
    Function1 var4 = (Function1)(new Function1(this.taskExecutor) { …
Run Code Online (Sandbox Code Playgroud)

code-coverage jacoco kotlin

7
推荐指数
1
解决办法
90
查看次数