import java.util.ArrayList;
import java.util.List;
/*
Вместе быстрее? Ща проверим :)
*/
public class Solution {
public static int threadCount = 10;
public static int[] testArray = new int[1000];
static {
for (int i = 0; i < Solution.testArray.length; i++) {
testArray[i] = i;
}
}
public static void main(String[] args) throws InterruptedException {
StringBuffer expectedResult = new StringBuffer();
for (int i = 1000 - 1; i >= 0; i--) {
expectedResult.append(i).append(" ");
}
initThreads();
StringBuffer result = new StringBuffer();
for (int i = 0; i < testArray.length; i++) {
result.append(testArray[i]).append(" ");
}
System.out.println(result);
System.out.println((result.toString()).equals(expectedResult.toString()));
}
public static void initThreads() throws InterruptedException {
List<Thread> threads = new ArrayList<Thread>(threadCount);
for (int i = 0; i < threadCount; i++) threads.add(new SortThread());
for (Thread thread : threads) thread.start();
for (Thread thread : threads) thread.join();
}
public static void sort(int[] array) {
for (int i = 0; i < array.length - 1; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i] < array[j]) {
int k = array[i];
array[i] = array[j];
array[j] = k;
}
}
}
}
public static class SortThread extends Thread{
@Override
public void run() {
Solution.sort(testArray);
}
}
}
Задачу решил! Но не понимаю, почему происходит изменение значения в result, мы ведь по идее создаем отдельную нить как объект в которой те же переменные экземпляра, методы и эти объекты выполняют свой run в своём потоке, каким образом он повлиял на работу остальных нитей и их переменные ? Я конечно может мыслю неправильно, но как я понимаю данную программу:
1. в методе main прогоняется цикл с значениями от 0-999
2. далее запускается метод initThreads() в котором происходит добавление нитей SortThread в коллекцию threads и далее запуск нитей, после которых идет join, то есть я как понял, происходит "наслаждение" нитей от метода main, то есть main отдыхает, пока выполняются нити из коллекции.
3. в самой же дочерней нити происходит сортировка значений походу дела "пузырьком" в коллекции testArray.
4. дальше мы передав в result значения каждой ячейки из коллекции testArray передаем на вывод в sout, после проверяем через equals сравнивая значения из result c expectedResult.
но почему значения в цикле не идут по порядку, а в разброс,некоторые наоборот еще повторяются, некоторые пропускают значения, у нас ведь 10 отдельных нитей, которые выполняют свои методы в своих новых объектах new SortThread.
Не кидайтесь помидорами только, тема многопоточности даётся непросто...Рустем
22 уровень
Появился такой вопрос...
Решен
Комментарии (5)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
velmik
12 августа 2022, 12:34
Таа-к 🙄 получается весь затык из-за того что главная нить класса SortThread создает 10 дочерних и в каждом потом через цикл через initThreads создается еще по 100 нитей дочерних уже дочек и так как у них общий start (потоки работают так как посчитает алгоритм JVM и так же по join) отсюда мы видим что значения в цикле не идут по порядку, а в разброс,некоторые наоборот еще повторяются, некоторые пропускают значения. Результат вызывается в main методом inittreads и т.д. по коду... занятноо получается 🤔
P.S извиняюсь за повтор, пока сам не проговорю , труднопонимается. )
0
Sergey MorozExpert
5 февраля 2019, 17:57решение
Нити то отдельные, но работают они с одним объектом, который никак от их работы не защищен. Образно говоря, работая параллельно, нити только мешают друг другу - нарасхват и как попало берут значения из уже отсортированных ячеек (отсюда и дубли); какие-то значения пропускают/затирают и т.п.
И джойн тут не спасает, потому как стартуют они в некоторой мере одновременно, а джойн начинает выполняться аж после запуска последней нити.
В общем, где-то здесь было - то ли в обсуждении задачи, то ли в вопросах - аналогию кто-то приводил: нити набрасываются на результирующую строку как свора собак, и каждая пытается наперебой ухватить свою часть.
И при этом сортировка не ускоряется в десять раз как на первый взгляд могло бы показаться.
+10
Рустем
6 февраля 2019, 06:08
я тут проанализировал немного код, понял почему идет разброс в данном случае. Потому что мы в нити используем метод sort, который вообще находится отдельно от нити SortThread, поэтому у него значения и в разброс идут, плюс и переменные экземпляра общие, это я про массив testArray. Происходит процесс сортировки в разных нитях и присваивает в массиве testArray значения в разброс из-за именно потока, так как каждый поток борится за процессорное время, один может выполняться быстрее другого, вот и происходит такой разброс значений в массиве после сортировки. Но я могу конечно ошибаться, но почитав и продебажив код несколько раз именно к этому мнению и пришел...
+1
Кирилл ОрловJava Developer в АО ЦПЛ
7 ноября 2019, 09:54
Вам выше правильно ответили, я еще начав читать код, тоже первым делом обратил внимание на странное использование join. Итог ожидаем, в общем-то. Тут либо synchronized надо было, либо join'ить при создании тредов сразу. А суть в процессорном времени, в других комментариях к вопросам по этой задаче, давали ответ про процессорное время и треды, оптимально кол-во процессоров/ядер+1 кол-во тредов. На один процессор с одним ядром нет смысла делать треды вообще, на два ядра будет два отдельных потока, а один процессор будет постоянно переключаться между тредами, никак не сокращая время.
+4
Art09
21 сентября 2021, 05:50
Фу сам немного разобрался и поэксперементировал с этой задачкой) Если закинуть synchronized блок в run класса SortThread, то числа выводятся по порядку, так как один поток захватывает монитор и другие потоки ждут.
+1