【发布时间】:2021-07-31 01:58:08
【问题描述】:
我正在尝试类似于Search for an element in array with threads 的东西。目标值将在 0 和 Integer.MAX_VALUE * 10L 之间,而不是使用实际数组,目标是通过使用简单的 for 循环找到该目标。
-
Searcher类将是线程本身。注意 for 循环的条件是i <= endIndex && Starter.running.get()。 -
Starter将创建线程并负责初始化其他所有内容。
有一个名为running 的变量类型AtomicBoolean 用于确保线程在其中一个找到元素时停止执行。问题在于,与单线程方法相比,多线程方法花费的时间是单线程方法的两倍。如果没有running,多线程代码会花费更长的时间。
我的目标是在找到目标时停止所有线程并知道是否找到目标。当然,如果目标不在范围内,那么线程将不得不检查整个段并且找不到任何东西。
示例输出:
Target is: 15794437641
Multithreaded option has now started...
Found target using multithreading: 15794437641
Found!
Multithreaded time: 00h:00m:08s.714
Multithreaded option has now completed.
Single thread option has now started...
Found target using single thread: 15794437641
Single thread time: 00h:00m:04s.226
Single thread option has now completed...
整个代码:
import java.util.concurrent.atomic.AtomicBoolean;
class Searcher implements Runnable {
private long target;
private long startIndex;
private long endIndex;
private long range;
public Searcher(long target, long startIndex, long endIndex, long range) {
this.target = target;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.range = range;
}
public void run() {
for (long i = startIndex; i <= endIndex && Starter.running.get(); i++) {
if (i == target) {
Starter.running.set(false);
Starter.isFound.set(true);
System.out.println("Found target using multithreading: " + i);
Thread.currentThread().interrupt();
}
}
}
}
public class Starter {
public static final AtomicBoolean running = new AtomicBoolean(true);
public static final AtomicBoolean isFound = new AtomicBoolean(false);
private static void findElementMultithreaded(
int threadNumber, long target, long range
) {
Thread[] threads = new Thread[threadNumber];//store threads created
long segment = range / threadNumber;
//create the threads but don't start them yet
for (int i = 0; i <= threadNumber - 1; i++) {
Searcher s;
Thread t;
long start = i * range;
long end = range - 1;
if (i == threadNumber - 1) {
s = new Searcher(target, start, end, segment);
} else {
s = new Searcher(target, start, start + end, segment);
}
t = new Thread(s);
threads[i] = t;
}
//start all threads
for (Thread t : threads) {
t.start();
}
//join all threads
for (Thread t : threads) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static void findElementSingleThread(long target, long size) {
for (long i = 0; i < size; i++) {
if (i == target) {
System.out.println("Found target using single thread: " + i);
break;
}
}
}
public static String getLapsedTime(long start, long end) {
long t = end - start;
long millis = t % 1000;
long x = t / 1000;
long seconds = x % 60;
x /= 60;
long minutes = x % 60;
x /= 60;
long hours = x % 24;
return String.format(
"%02dh:%02dm:%02ds.%03d", hours, minutes, seconds, millis
);
}
public static void main(String[] args) {
int numberOfThreads = 8;
long size = Integer.MAX_VALUE * 10L;
long target = (long) (Math.random() * size);
System.out.println("Target is: " + target);
long start;
long end;
System.out.println("Multithreaded option has now started...");
start = System.currentTimeMillis();
findElementMultithreaded(numberOfThreads, target, size);
if (isFound.get()) {
System.out.println("Found!");
}
end = System.currentTimeMillis();
System.out.println("Multithreaded time: " + getLapsedTime(start, end));
System.out.println("Multithreaded option has now completed.\n");
//
System.out.println("Single thread option has now started...");
start = System.currentTimeMillis();
findElementSingleThread(target, size);
end = System.currentTimeMillis();
System.out.println("Single thread time: " + getLapsedTime(start, end));
System.out.println("Single thread option has now completed...");
}
}
【问题讨论】:
-
您包括线程创建和终止的时间;这可能很重要。
-
正在共享的运行变量是 volatile 吗? stackoverflow.com/questions/13582395/…
-
@iggy,即使我只在启动线程后对代码进行计时,它仍然给出相同的时间。
-
@MauricioGraciaGutierrez 似乎没有任何改变。
-
@M.AlJumaily 我提供了一个按预期工作的答案(恕我直言)
标签: java multithreading