Пример использования runnable

public class CreateThreadRunnableExample implements Runnable {

    public void run() {

        for (int i = 0; i < 5; i++) {
            System.out.println("Child Thread : " + i);

            try {
                Thread.sleep(50);
            } catch (InterruptedException ie) {
                System.out.println("Child thread interrupted! " + ie);
            }
        }

        System.out.println("Child thread finished!");
    }

    public static void main(String[] args) {

        Thread t = new Thread(new CreateThreadRunnableExample(), "My Thread");

        t.start();

        for (int i = 0; i < 5; i++) {

            System.out.println("Main thread : " + i);

            try {
                Thread.sleep(100);
            } catch (InterruptedException ie) {
                System.out.println("Child thread interrupted! " + ie);
            }
        }
        System.out.println("Main thread finished!");
    }
}

в этой программе два метода сна используются для разного времени.,, так что если время выполнения основного потока, то дочерний поток должен запускаться 2 раза. Но он работает только один раз... мы принимаем концепцию runnable или running state.... тогда, когда основной поток заканчивается, тогда 2 дочерних потока будут в состоянии готовности, тогда почему выполняется только один дочерний поток.

Ответ 1

Метод sleep не точен на 100%, как указано в JavaDoc:

public static void sleep (long millis)                   throws InterruptedException

Заставляет текущий исполняемый поток спать (временно прекратить выполнение) для заданное количество миллисекунд, с учетом точности и точность системных таймеров и планировщиков. Нить не теряет владение любыми мониторами.

Таким образом, в основном код может работать как ожидалось, а в других случаях нет.

Кроме того, вы, кажется, начинаете только 1 ребенка, так почему вы ожидаете 2?

EDIT: теоретически да, дочерний поток должен выполняться дважды, пока поток main спит. При этом, как объясняется в JavaDoc, точность, с которой выполняется метод sleep, зависит от системы, на которой она работает, поэтому время от времени вы можете заставить ее работать так, как ожидалось, а иногда и нет. Например, у вас могут быть сценарии, в которых поток main засыпает, скажем, 97 миллисекунд, а не 100, а у ребенка - сон, скажем, 53 миллисекунды. Это заставит ребенка выполнить только один раз.

Другим вариантом было бы сделать что-то вроде этого: while (currentTime <= timeNeededToElapse) { currentTime=... }. Это приводит к жесткому циклу while, который может обеспечить лучший контроль, но по-прежнему я до сих пор, на мой взгляд, не на 100% точнее, не говоря уже о том, что вы будете потреблять циклы процессора, чтобы эффективно ничего не делать, поэтому его следует использовать с осторожностью.

Ответ 2

Прежде всего, вы добавили System.out.println( "Ребенок прерывается!" + ie); как для основного, так и для дочернего потока, это опечатка...

Попробуйте это... Оба потока запущены (Основной и дочерний поток)

Основной метод этой программы помещается в нижнюю часть основного потока, созданного JVM, и метод Main создает другой стек Runtime и помещает в него дочерний поток.

public class DemoThread implements Runnable {

    public void run() {

        for (int i = 0; i < 3; i++) {
            System.out.println("Child Thread ");

            try {
                Thread.sleep(200);
            } catch (InterruptedException ie) {
                System.out.println("Child thread interrupted! " + ie);
            }
        }

        System.out.println("Child thread finished!");
    }

    public static void main(String[] args) {

        Thread t = new Thread(new DemoThread ());

        t.start();

        for (int i = 0; i < 3; i++) {

            System.out.println("Main thread);

            try {
                Thread.sleep(200);
            } catch (InterruptedException ie) {
                System.out.println("Child thread interrupted! " + ie);
            }
        }
        System.out.println("Main thread finished!");
    }
}

Ответ 3

Вы запускаете только один дочерний поток, так почему вы ожидаете двух?

О тайм-аутах время сна не является точным, поэтому, пока один поток спит в течение 100 мс, другой может или не может спать дважды в течение 50 мс. Это классический пример условия гонки . Если вы запускаете пример кода несколько раз, вы можете увидеть два дочерних потока сообщений в некоторых случаях и один в других случаях.

Ответ 4

ПОПРОБУЙТЕ ЭТО

  public class Test implements Runnable{

        public void run() {

            for (int i = 0; i < 5; i++) {
                System.out.println("CHILD THREAD : " + i);

                try {
                    Thread.sleep(50);
                } catch (InterruptedException ie) {
                    System.out.println("CHILD THREAD INTERRUPTED! " + ie);
                }
            }

            System.out.println("CHILD THREAD FINISHED!");
        }

        public static void main(String[] args) {

            Thread t = new Thread(new Test());

            t.start();

            for (int i = 0; i < 5; i++) {
                System.out.println("MAIN THREAD : " + i);
                try {
                    Thread.sleep(200);
                } catch (InterruptedException ie) {
                    System.out.println("CHILD THREAD INTERRUPTED! " + ie);
                }
            }
            System.out.println("MAIN THREAD FINISHED!");
        }
    }