Заставить нити работать должным образом - PullRequest
5 голосов
/ 07 декабря 2010

Я только начал изучать темы и столкнулся с неправильным пониманием того, как они работают.

Вот мой класс:

public class MyThread extends Thread {
    private static int NUM = 0;
    private int id;

    public MyThread() {
        id = NUM++;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new MyThread().start(); 
        }
    }

    public void run() {
        System.out.println(id + " started");

        try {
            Process p = Runtime.getRuntime().exec("javac -version");
            p.waitFor();
        } catch (Exception e) {
            System.out.println("Call a doc!");
        }

        System.out.println(id + " finished");
    }
}

/*
Just a sidenote.
I am creating new javac process just to slow an application down.
Simple System.out.println(…) is a way faster.
*/

Почему я всегда получаю все «… Начались» сообщения сначала, а после этого «… закончены» сообщения?Независимо от того, сколько потоков я запустил, я всегда вижу:

0 started
1 started
2 started
3 started
4 started
5 started
6 started
7 started
8 started
9 started
0 finished
1 finished
3 finished
4 finished
8 finished
5 finished
2 finished
6 finished
9 finished
7 finished

Разве потоки не предназначены для распараллеливания выполнения?
Может быть, мне нужно что-то синхронизировать?Или совершил неосторожную ошибку?Или ...?
Объясните, пожалуйста.

ОБНОВЛЕНИЕ:

Почему я не вижу, скажем:

0 started
1 started
0 finished
2 started
1 finished
2 finished

СпасибоВы все на лечение.

Ответы [ 5 ]

2 голосов
/ 07 декабря 2010

выглядит хорошо. Вы можете видеть из своего вывода, что потоки чередуются. потоки запускаются, переключаются в контекст и выбираются планировщиком, вы можете видеть, где поток 8, например, опережает поток 5. Если бы все числа были в порядке последовательно, это было бы странно, но это кажется хорошим.

Используйте время сна, как предлагает Питер Лори, чтобы вы могли изменить продолжительность каждого потока. Как показывает ваш пример, запуск процесса занимает столько времени, что кажется разумным, что все ваши потоки должны быть запущены до какого-либо завершения.

2 голосов
/ 07 декабря 2010

Потоки параллельны. В противном случае вы бы увидели, что каждый поток «закончен», прежде чем следующий «запустится»

Простой способ замедлить поток - использовать Thread.sleep (10 * 1000); спать 10 секунд (10000 миллисекунд)

РЕДАКТИРОВАТЬ: простой способ увидеть чередование потоков - это иметь пул потоков фиксированного размера.

ExecutorService pool = Executors.newFixedThreadPool(4);
for (int i = 0; i < 10; i++) {
    final int id = i;
    pool.submit(new Callable<Void>() {
        public Void call() throws InterruptedException {
            System.out.println(id + " started");
            Thread.sleep(1000);
            System.out.println(id + " finished");
            return null;
        }
    });
}

печать

0 started
1 started
2 started
3 started
0 finished
4 started
1 finished
5 started
2 finished
6 started
3 finished
7 started
4 finished
8 started
5 finished
6 finished
9 started
7 finished
8 finished
9 finished
1 голос
/ 07 декабря 2010

Если вы хотите увидеть «случайное» начало и конец, вы можете добавить

Thread.sleep(new Random().nextInt(1000)); 

или похожие на нити.

1 голос
/ 07 декабря 2010

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

1 голос
/ 07 декабря 2010

Если вы поместите простой цикл для подсчета от 1 до 20 в методе run (), вы можете лучше увидеть чередование выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...