Проблема с потоками в java

195
28 ноября 2018, 14:20

есть код

class SomeThread extends Thread {
    public void run() {
        for (int i=0; i < 10; i++)
            System.out.println(i);
    }
}
public class Main {
    public static void main(String[] args) {
        SomeThread test = new SomeThread();
        test.start();
        SomeThread test2 = new SomeThread();
        test2.start();

    }
}

в теории должны били вывестись числа от 0 до 9 потоком. Но они выводятся по очереди, с начала первые 10 чисел от 0 до 9, затем следующее 10 чисел от 0 до 9. Подскажите в чём проблема ?

Answer 1

Причина в неодновременном запуске потоков. Используйте для их синхронного запуска CountDownLatch:

private static final CountDownLatch countDownLatch = new CountDownLatch(1);
class SomeThread extends Thread {
    public void run() {
        try {
            countDownLatch.await();
            for (int i = 0; i < 10; i++) {
                System.out.println(i);
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(TestString.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
public class Main {
    public static void main(String[] args) {
        SomeThread test = new SomeThread();
        test.start();
        SomeThread test2 = new SomeThread();
        test2.start();
        countDownLatch.countDown();
    }
}
Answer 2

Тут нет проблемы. Просто нужно осознавать, что создание потока требует некоторых накладных расходов по времени. В итоге получается ситуация, что Вы создали первый поток, запустили его и только потом создаете второй поток. В итоге, когда второй поток создался и Вы запускаете его - первый уже отработал.

Это легко проверить путем увеличения цикла (попробуйте 100, 1000 и тд).

Вариант решения проблемы - сперва создать 2 потока, потом их запустить.

Answer 3

Советую тебе изучить жц потоков.Запуск потока не дает никакую гарантию на то что поток будет работать.У джава есть обработчик потоков он сам определяет какой поток будет выполнятся так же он сам определят когда остановить поток поэтому советую тебе 100 раз перезапустить программу и при запуске программа по разному будет себя вести

Answer 4
class SomeThread implements Runnable {
    Thread thrd;
    SomeThread(String name){
        thrd = new Thread(this, name);
        thrd.start();
    }
    public void run() {
        for (int i=0; i < 10; i++) {
            System.out.println(i + thrd.getName());
            try{
                Thread.sleep(1000);
            } catch (InterruptedException exc) {
                System.out.println("Exception in added thread : " + exc);
            } 
        }
        System.out.println("End thread : " + thrd.getName());
    }
}
class Test {
    public static void main(String[] args) {
        SomeThread test1 = new SomeThread("test1");
        SomeThread test2 = new SomeThread("test2");
        try {
            Thread.sleep(10000);
            test1.thrd.join();
            test2.thrd.join();
        } catch(InterruptedException exc) {
            System.out.println("Exception in main thread : " + exc);
        }
    }
}

Пару моментов:

  • Если в классе реализующем многопоточность не переопределяются методы кроме run(), хорошим тоном является расширение интерфейса Runnable, в котором объявлен, лишь метод run().
  • Результат выполнения многопоточной программы зависит от начинки Вашего пк, в частности от процессора.
Answer 5

Ни в чем. У тебя 3 потока: test, test2 и main. main запускает test и идет дальше к test2.start(). Если нужно поочередно, вставь следующее после test.start()

test.join();

public class SomeThread extends Thread {
    @Override
    public void run() {
        for (int i=0; i < 10; i++) {
            System.out.println(i);
        }
    }
    public static void main(String[] args) throws InterruptedException {
        SomeThread test = new SomeThread();
        test.start();
        test.join();
        SomeThread test2 = new SomeThread();
        test2.start();
    }
}
Answer 6

Может дело в том что у println есть так же своя внутренняя синхронизация, и его просто захватывает потом в цикле и не отпускает до окончания цикла. Плюс к тому, код может выполняется быстрее чем приходит прерывание и выкидывает его из ядра.

public void println(int x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}
READ ALSO
ошибка при работе с SceneBuilder в Eclipse

ошибка при работе с SceneBuilder в Eclipse

При запуске программы вылетает такая ошибка и ничего не запускается:

222
Unknown animator name: alpha

Unknown animator name: alpha

Получаю такую ошибку (заголовок), код:

177
Фильтр запроса из БД

Фильтр запроса из БД

Приходит запрос получить все товары, соответствующие фильтрам 14 и 15Я делаю запрос в базу данных и мне выдаёт такой список

150