有可能在不破坏逻辑的情况下减少线路数量吗



我需要做一个测试-哪个列表更快。为此,我在一个新线程中运行每个测试。我在一个单独的类中为每个线程创建可运行的方法。我得到了一个相当单调的代码,这是一个DRY违规。也许有人知道我如何在不破坏DRY的情况下同时运行所有线程?

public class ThreadsManager {
public static boolean stopThreads = false; //We change this variable MainActivity
public static long timeOfStartTest = 0;
public void startCollThreads() {
stopThreads = false;
timeOfStartTest = new Date().getTime();
CollRunnable collRunnable = new CollRunnable();
new Thread(collRunnable.addBeg(new ArrayList())).start();
new Thread(collRunnable.addBeg(new LinkedList())).start();
new Thread(collRunnable.addBeg(new CopyOnWriteArrayList())).start();
new Thread(collRunnable.addMid(new ArrayList())).start();
new Thread(collRunnable.addMid(new LinkedList())).start();
new Thread(collRunnable.addMid(new CopyOnWriteArrayList())).start();
new Thread(collRunnable.addEnd(new ArrayList())).start();
new Thread(collRunnable.addEnd(new LinkedList())).start();
new Thread(collRunnable.addEnd(new CopyOnWriteArrayList())).start();
new Thread(collRunnable.search(new ArrayList())).start();
new Thread(collRunnable.search(new LinkedList())).start();
new Thread(collRunnable.search(new CopyOnWriteArrayList())).start();
new Thread(collRunnable.removeBeg(new ArrayList())).start();
new Thread(collRunnable.removeBeg(new LinkedList())).start();
new Thread(collRunnable.removeBeg(new CopyOnWriteArrayList())).start();
new Thread(collRunnable.removeMid(new ArrayList())).start();
new Thread(collRunnable.removeMid(new LinkedList())).start();
new Thread(collRunnable.removeMid(new CopyOnWriteArrayList())).start();
new Thread(collRunnable.removeEnd(new ArrayList())).start();
new Thread(collRunnable.removeEnd(new LinkedList())).start();
new Thread(collRunnable.removeEnd(new CopyOnWriteArrayList())).start();
}
}
public class CollRunnable {
//region Adding in the beginning
public Runnable addBeg(List list) {
return () -> {
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.add(0, "");
}
updateViewModelValue(1,"Adding nin the beginning", list);
};
}
//endregion
//region Adding in the middle
public Runnable addMid(List list) {
return () -> {
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.add(0, "");
}
updateViewModelValue(2, "Adding nin the middle", list);
};
}
//endregion
//region Adding in the end
public Runnable addEnd(List list) {
return () -> {
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.add("");
}
updateViewModelValue(3, "Adding nin the end", list);
};
}
//endregion
//region Search
public Runnable search(List list) {
return () -> {
list.add(0);
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.get(0);
}
updateViewModelValue(4, "Search nby value", list);
};
}
//endregion
//region Removing in the beginning
public Runnable removeBeg(List list) {
return () -> {
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.add("");
list.remove("");
}
updateViewModelValue(5, "Removing nin the beginning", list);
};
}
//endregion
//region Removing in the middle
public Runnable removeMid(List list) {
return () -> {
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.add("");
list.remove("");
}
updateViewModelValue(6, "Removing nin the middle", list);
};
}
//endregion
//region removing in the end
public Runnable removeEnd(List list) {
return () -> {
for (int i = 0; i <= elementsNumber; i += 1) {
if (stopThreads) {
return;
}
list.add("");
list.remove("");
}
updateViewModelValue(7, "Removing nin the end", list);
};
}
//endregion
private void updateViewModelValue(int numberOfTest, String testName, List list) {
new Handler(Looper.getMainLooper()).post(() -> {
DataClass dataClass = new DataClass(numberOfTest,testName, list, new Date().getTime() - timeOfStartTest);
getCollInstance().viewModel.testResult.setValue(dataClass);
});
}
}

一种方法是分离列表的创建。例如,在界面的帮助下:

@FunctionalInterface
public interface ListFactory {
List create();
}
// In ThreadsManager
public void orquestate() {
startCollThreads(() -> new ArrayList());
startCollThreads(() -> new LinkedList());
startCollThreads(() -> new CopyOnWriteArrayList());
}
private void startCollThreads(ListFactory listFactory) {
stopThreads = false;
timeOfStartTest = new Date().getTime();
CollRunnable collRunnable = new CollRunnable();
new Thread(collRunnable.addBeg(listFactory.create())).start();
new Thread(collRunnable.addMid(listFactory.create())).start();
// Other steps
}

这与列表类型首先开始的步骤并不完全相同,但我不知道这对您是否重要。

您可以使用线程池API进行此提议。例如ExecutorService.html.invokeAll

例如:

try {
Runnable routine = (List<?> args) -> { // add your thread routine implementation }
// you can use same routine for all tasks, or make any combination such as 3 different routines in list etc
Runnable[] allTasks = new Runnable[8];
Arrays.fill(allTasks, routine);
ExecutorService pool =  Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
// invoke all tasks from array in thread pool
pool.invokeAll( Arrays.asList(allTasks) );
// stop pool and await for it termination
pool.shutdown();
if (!pool.awaitTermination(60, TimeUnit.MINUTES)) {
pool.shutdownNow();
}
}
} catch (InterruptedException ie) {
pool.shutdownNow();
Thread.currentThread().interrupt();
}

您可以利用供应商功能界面。如下所示,提取一个方法,该方法将测试作为参数传递到列表类型上的给定函数

private void run_test(Function<List, Runnable> collRunnable) {
new Thread(collRunnable.apply(new ArrayList())).start();
new Thread(collRunnable.apply(new LinkedList())).start();
new Thread(collRunnable.apply(new CopyOnWriteArrayList())).start();
}

然后调整您的startCollThreads方法:

public void startCollThreads() {
stopThreads = false;
timeOfStartTest = new Date().getTime();
CollRunnable collRunnable = new CollRunnable();
run_test(collRunnable::addBeg);
run_test(collRunnable::addMid);
run_test(collRunnable::addEnd);
run_test(collRunnable::search);
run_test(collRunnable::removeBeg);
run_test(collRunnable::removeMid);
run_test(collRunnable::removeEnd);
}

旁注

您正在使用Raw类型,您应该避免这种情况,请参阅此来源了解原因。

您还可以通过参数化作为参数传递的列表来使其更通用:

private void run_test(Function<List, Runnable> collRunnable, Supplier<List>... lists) {
for (Supplier<List> list : lists) {
new Thread(collRunnable.apply(list.get())).start();
}
}

然后你可以用不同的列表调用方法:

run_test(collRunnable::addBeg, ArrayList::new, LinkedList::new, CopyOnWriteArrayList::new);

run_test(collRunnable::addBeg, ArrayList::new);

相关内容

最新更新