Поток нитей в Java - PullRequest
       6

Поток нитей в Java

3 голосов
/ 08 сентября 2011

Я пытаюсь понять программу ниже. Если я вызываю new ReaderThread().start(), он работает нормально, но если я звоню new ReaderThread().run(), приложение переходит в бесконечный цикл. В чем разница?

public class Contention {

    private static boolean ready;
    private static int number;

    private static class ReaderThread extends Thread {
        public void run() {
                 while (!ready){
                System.out.println("ready ..."+ready);
                Thread.yield();}
            System.out.println(number);
           // }
        }
    }


    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new ReaderThread().run();
        number = 42;
        ready = true;

    }

}

Ответы [ 6 ]

11 голосов
/ 08 сентября 2011

когда вы звоните run(), вы делаете это в той же теме. Это просто вызов метода.

Когда вы вызываете start() для запуска другого потока для вызова run()

Это одна из причин, по которой не стоит расширять Thread, а вместо этого реализовывать Runnable, который вы оборачиваете потоком. Это один из многих потенциальных источников путаницы.


Вот вам соответствующий тизер

static String name = "Peter Lawrey";
static String state = "Washington";

static String getName() {
  return name;
}

static String getState() {
  return state;
}

static class NamedThread extends Thread {
  @Override
  public void run() {
    System.out.println(getName()+" - "+getState());
  }
}

public static void main(String... args) throws InterruptedException {
  new NamedThread().start();
}

печать

Thread-0 - RUNNABLE

Вы можете понять, почему?

4 голосов
/ 08 сентября 2011

run() - это просто метод, который не запускает новый поток, поэтому main() никогда не получит установить ready на true.

Только start() фактически создаст отдельный поток выполнения - это то, что вам нужно.

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

2 голосов
/ 08 сентября 2011

Если вы используете new ReaderThread().start();, вы фактически создаете новый экземпляр потока, который будет работать в фоновом режиме, и main() возобновляет его дальнейшее выполнение.

Но new ReaderThread().run(); создает экземпляр этого класса и выполняет обычный вызов метода для метода run(), поэтому main() должен ждать, пока run() завершит выполнение, и вернуть элемент управления обратно в main ( ), который в вашем случае представляет собой бесконечный цикл.

Если вы хотите начать новый поток, начните с использования ReaderThread().start();, это правильный способ запустить поток, альтернативы этому нет.

2 голосов
/ 08 сентября 2011

Внимательно прочитайте о потоках в Java (например, http://download.oracle.com/javase/tutorial/essential/concurrency/)

Когда вы вызываете метод run (), вы вызываете его так же, как любой другой метод, и он будет работать в том же потоке, что и вызывающий метод.

1 голос
/ 08 сентября 2011

Если у вас есть new ReaderThread().run();, он находится в той же теме, а ready = true; никогда не достигнуто.

Но когда вы вызываете new ReaderThread().start(), он запускает новый поток, и основной поток также продолжается и нажимает ready = true; - что приведет к созданию потока, созданного из цикла ...

1 голос
/ 08 сентября 2011
public class Contention {

    private static boolean ready;
    private static int number;

    private static class ReaderThread extends Thread {
        public void run() {
                 while (!ready){
                System.out.println("ready ..."+ready);
                Thread.yield();}
            System.out.println(number);
           // }
        }
    }




    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new ReaderThread().run();//control goes to run() method

//and it keeps running and next line of code where you set ready=true will not be executed
        number = 42;
        ready = true;

    }

}

изм:

потому что потоки не запускаются вместе (но одновременно), но ОС решает, какой из них выполняется, и гарантирует, что каждый поток получает свой собственный шанс на основе TimeShared (или любого алгоритма). так что в вашем случае other thread получает шанс первым и исполняется до того, как поток main() получит шанс запустить и установить ready = true., но если вы снова запустите свой код, возможен и другой случай. где ready = true; установлено и Thread не войдет в While() цикл.

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