I need to make a test - which of the lists is faster. To do this, I run each test in a new thread. I create the runnable method for the each thread in a separate class. I get a rather monotonous code, this is a DRY violation. Maybe someone knows how I can run all threads at the same time without breaking 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);
        });
    }
}
 
     
     
    