Подтвердить что ты не робот

Почему локальные переменные потоки в Java

Я читал многопоточность в Java, и я сталкивался с этим

Локальные переменные являются потокобезопасными в Java.

С тех пор я думал, как/Почему локальные переменные являются потокобезопасными.

Может кто-нибудь, пожалуйста, дайте мне знать.

4b9b3361

Ответ 1

Когда вы создаете поток, у него будет свой собственный стек. Два потока будут иметь два стека, а один поток никогда не будет делиться своим стеком с другим потоком.

Все локальные переменные, определенные в вашей программе, будут выделены в стеке в стеке (как прокомментировал Jatin, здесь здесь означает ссылочное значение для объектов и значение для примитивных типов) (Каждый вызов метода потоком создает фрейм стека самостоятельно стек). Как только выполнение метода будет завершено этим потоком, стек стека будет удален.

Есть замечательная лекция Стэнфордский профессор в youtube, который может помочь вам в понимании этой концепции.

Ответ 2

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

public void someMethod(){

   long threadSafeInt = 0;

   threadSafeInt++;
}

Локальные ссылки на объекты немного разные. Сама ссылка не разделяется. Объект, на который ссылается, однако, не сохраняется в каждом потоке локального стека. Все объекты хранятся в общей куче. Если объект, созданный локально, никогда не ускользает от метода, в котором он был создан, он является потокобезопасным. Фактически вы также можете передать его другим методам и объектам, если ни один из этих методов или объектов не делает переданный объект доступным для других потоков

Ответ 3

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

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

Рассмотрим эти два случая:

public class NotThreadsafe {
    int x = 0;
    public int incrementX() {
        x++;
        return x;
    }
}

public class Threadsafe {
    public int getTwoTimesTwo() {
        int x = 1;
        x++;
        return x*x;
    }
}

В первом случае два потока, выполняющиеся в одном экземпляре NotThreadsafe, будут видеть один и тот же x. Это может быть опасно, потому что потоки пытаются изменить x! Во втором случае два потока, выполняющиеся на одном экземпляре Threadsafe, будут видеть совершенно разные переменные и не могут влиять друг на друга.

Ответ 4

В дополнение к другим ответам, таким как Nambari's.

Я хотел бы указать, что вы можете использовать локальную переменную в методе anoymous type:

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

Рассмотрим этот незаконный код:

public void nonCompilableMethod() {
    int i=0;
    for(int t=0; t<100; t++)
    {
      new Thread(new Runnable() {
                    public void run() {
                      i++; //compile error, i must be final:
                      //Cannot refer to a non-final variable i inside an
                      //inner class defined in a different method
                    }
       }).start();
     }
  }

Если java разрешило это (например, С# делает через "закрытие" ), локальная переменная перестала быть потокобезопасной при любых обстоятельствах. В этом случае значение i в конце всех потоков не гарантируется 100.

Ответ 5

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

Однако, внимательно следите за тем, что именно подразумевается под этим: только записи в эту переменную являются потокобезопасными; вызывающие методы на объекте, которые он ссылается на , по сути не являются потокобезопасными. То же самое касается непосредственного обновления переменных объекта.

Ответ 6

В потоке будет свой собственный стек. Два потока будут иметь два стека, а один поток никогда не делится своим стеком с другим потоком. Локальные переменные хранятся в каждом потоке собственного стека. Это означает, что локальные переменные никогда не разделяются между потоками.

Ответ 7

В основном четыре типа хранилища находятся в java для хранения информации о классе и данных:

Область метода, куча, стек JAVA, ПК

поэтому область "Метод" и "Куча" разделяются всеми потоками, но каждый поток имеет свой собственный стек JAVA и ПК и который не используется другими нитями.

Каждый метод в java является фреймом Stack. поэтому, когда один метод вызывается потоком, который стек стека загружается в его стек JAVA. Вся локальная переменная, которая присутствует в этом стеке стека и связанный стек операнда, не разделяется другими. ПК будет иметь информацию о следующей инструкции для выполнения в байтовом методе метода. поэтому все локальные переменные являются БЕЗОПАСНЫМИ РЕЖИМАМИ.

@Weston также дал хороший ответ.

Ответ 8

Мне нравится Дженков объяснение

Стек потока содержит все локальные переменные для каждого выполняемого метода (все методы в стеке вызовов). Поток может получить доступ только к своему стеку потоков. Локальные переменные, созданные потоком, невидимы для всех других потоков, кроме потока, который его создал. Даже если два потока исполняют один и тот же код, эти два потока все равно будут создавать локальные переменные этого кода в каждом своем стеке потоков. Таким образом, каждый поток имеет свою версию каждой локальной переменной.

Все локальные переменные примитивных типов (логические, байтовые, короткие, char, int, long, float, double) полностью хранятся в стеке потоков и поэтому не видны другим потокам, Один поток может передать копию примитивной переменной другому потоку, но он не может совместно использовать примитивную локальную переменную.

Куча содержит все объекты, созданные в приложении Java, независимо от того, какой поток создал объект. Это включает в себя версии объектов примитивных типов (например, Byte, Integer, Long и т.д.). Неважно, был ли объект создан и назначен локальной переменной или создан как переменная-член другого объекта, этот объект все еще сохраняется в куче.

Локальная переменная может быть примитивного типа, и в этом случае она полностью сохраняется в стеке потоков.

Локальная переменная также может быть ссылкой на объект. В этом случае ссылка (локальная переменная) сохраняется в стеке потоков, но сам объект object, если он хранится в куче.

Пожалуйста, прочитайте больше здесь