Каковы локальные переменные в потоке? - PullRequest
2 голосов
/ 15 января 2020

Согласно Java Параллелизму на практике,

Каждый поток имеет свой собственный программный счетчик, стек и локальные переменные.

У меня путаница с утверждением "локальные переменные". Что здесь означают локальные переменные? Означает ли это локальную копию разделяемой переменной в потоке, например, если два потока асинхронно читают одну глобальную переменную, каждый поток содержит копию этой переменной в своем коде выполнения / пути?

Или это относится к переменным, которые объявлены и созданы явно внутри потоков и которые не являются общими?

Ответы [ 2 ]

6 голосов
/ 15 января 2020

Локальные переменные - это просто переменные локальной области видимости. См. JLS 6.3 для получения дополнительной информации и примеров.

В следующем методе

void method(String param1, int param2) {
    String concat = param1 + param2;
    if(concat.length() > 2) {
        int length = concat.length();
        System.out.println("concat is " + length + " character long");
    }
}

Локальные переменные включают аргументы метода (param1, param2), переменные объявлено в методе (concat, length)

По вашему вопросу, это переменные, срок жизни которых не выходит за рамки выполнения метода.

1 голос
/ 15 января 2020

Рассмотрим, когда потоки запускаются - например:

public class MyThread implements Runnable {

    private String name;

    public void kickOff() {

        Thread thread1 = new Thread();
        thread1.start();
        Thread thread2 = new Thread();
        thread2.start();
    }

    public void run() {
        Person person = findSomeRandomPerson();
        printPerson(person);
    }

    public void printPerson(Person person) {
        String desc = person.toString();
        doSomething(desc);

        // This is bad - the threads can interfere
        this.name = "Hello " + desc;
        doMore(this.name)            
    }
}

Итак, здесь у нас есть один экземпляр класса MyThread с двумя работающими потоками - оба начинаются с метода run().

Что означает бит local variables, так это то, что локальные переменные в методах run() (и последующие вызовы) не будут влиять друг на друга между потоками (даже если они выполняются в контексте одного и того же экземпляра класса MyThread) .

Например, если thread1 получает Person fred, а thread2 получает Person bill, вызов thread1 printPerson всегда гарантированно будет desc описанием fred (и аналогично desc всегда будет описание для счета в потоке 2).

РЕДАКТИРОВАТЬ В ДОБАВИТЬ: В дополнение к вашему вопросу о том, «если два потока читают одну глобальную переменную асинхронно, каждый поток содержит копию этой переменной»

Нет, потоки не содержат свои собственные копии объектов. Например, рассмотрим переменную экземпляра name выше.

Это переменная экземпляра MyThread. Как указывалось ранее, оба потока выполняются в контексте ТОГО ЖЕ МОМЕНТА MyThread. Это означает, что они оба получают доступ к ОДНОМУ ИМЕННОМУ имени. Это означает, что когда один изменит «имя», другой увидит это изменение.

В результате установка this.name и вызов doMore(this.name), как это плохо. Например, следующая последовательность действий вполне возможна:

  1. Поток 1 устанавливает this.name в "Hello fred"
  2. Поток 2 устанавливает this.name в "Hello bill"
  3. Поток 1 вызывает doMore (this.name)

Это приведет к тому, что поток 1 вызовет doMore("Hello bill"), поскольку потоки обращаются к одному и тому же объекту (а не к собственной копии объекта). ).

Добро пожаловать в удивительный мир гоночных условий!

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