p2k*_*2kr 8 java parallel-processing performance multithreading java-threads
这是查找 LCM 和 HCF 之和等于该数字的第一对数字(1 除外)的代码。
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
class PerfectPartition {
static long gcd(long a, long b) {
if (a == 0)
return b;
return gcd(b % a, a);
}
// method to return LCM of two numbers
static long lcm(long a, long b) {
return (a / gcd(a, b)) * b;
}
long[] getPartition(long n) {
var ref = new Object() {
long x;
long y;
long[] ret = null;
};
Thread mainThread = Thread.currentThread();
ThreadGroup t = new ThreadGroup("InnerLoop");
for (ref.x = 2; ref.x < (n + 2) / 2; ref.x++) {
if (t.activeCount() < 256) {
new Thread(t, () -> {
for (ref.y = 2; ref.y < (n + 2) / 2; ref.y++) {
long z = lcm(ref.x, ref.y) + gcd(ref.x, ref.y);
if (z == n) {
ref.ret = new long[]{ref.x, ref.y};
t.interrupt();
break;
}
}
}, "Thread_" + ref.x).start();
if (ref.ret != null) {
return ref.ret;
}
} else {
ref.x--;
}
}//return new long[]{1, n - 2};
return Objects.requireNonNullElseGet(ref.ret, () -> new long[]{1, n - 2});
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long n = sc.nextLong();
long[] partition = new PerfectPartition().getPartition(n);
System.out.println(partition[0] + " " + partition[1]);
}
}
Run Code Online (Sandbox Code Playgroud)
我想在找到第一对后立即停止代码执行。但是,该main
线程只是继续运行并打印1
和n-1
。
什么是限制数量的最佳解决方案?线程数(<256,因为 n 的范围是2
到max of long
)?
预期产出( n=4
): 2 2
预期产出( n=8
): 4 4
首先,您错过了在线程上调用“start”的机会。
new Thread(t, () -> {
...
...
}, "Thread_" + ref.x).start();
Run Code Online (Sandbox Code Playgroud)
说到你的问题,要限制可以使用线程池的线程数量,例如 Executors.newFixedThreadPool(int nThreads)。
要停止执行,您可以让主线程等待单个计数 CountDownLatch,并在工作线程中成功匹配时对锁存器进行倒计时,并在锁存器等待完成时关闭主线程池。
正如您所问,这里是使用线程池和 CountDownLatch 的示例代码:
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class LcmHcmSum {
static long gcd(long a, long b) {
if (a == 0)
return b;
return gcd(b % a, a);
}
// method to return LCM of two numbers
static long lcm(long a, long b) {
return (a / gcd(a, b)) * b;
}
long[] getPartition(long n) {
singleThreadJobSubmitter.execute(() -> {
for (int x = 2; x < (n + 2) / 2; x++) {
submitjob(n, x);
if(numberPair != null) break; // match found, exit the loop
}
try {
jobsExecutor.shutdown(); // process the already submitted jobs
jobsExecutor.awaitTermination(10, TimeUnit.SECONDS); // wait for the completion of the jobs
if(numberPair == null) { // no match found, all jobs processed, nothing more to do, count down the latch
latch.countDown();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
try {
latch.await();
singleThreadJobSubmitter.shutdownNow();
jobsExecutor.shutdownNow();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
return Objects.requireNonNullElseGet(numberPair, () -> new long[]{1, n - 2});
}
private Future<?> submitjob(long n, long x) {
return jobsExecutor.submit(() -> {
for (int y = 2; y < (n + 2) / 2; y++) {
long z = lcm(x, y) + gcd(x, y);
if (z == n) {
synchronized(LcmHcmSum.class) { numberPair = new long[]{x, y}; }
latch.countDown();
break;
}
}
});
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long n = sc.nextLong();
long[] partition = new LcmHcmSum().getPartition(n);
System.out.println(partition[0] + " " + partition[1]);
}
private static CountDownLatch latch = new CountDownLatch(1);
private static ExecutorService jobsExecutor = Executors.newFixedThreadPool(4);
private static volatile long[] numberPair = null;
private static ExecutorService singleThreadJobSubmitter = Executors.newSingleThreadExecutor();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
226 次 |
最近记录: |