2014-02-13 2 views
0

Этот код не имеет внутренних классов:Темы внутреннего класса

class Threads1 implements Runnable { 

    int x = 0; 

    public void run(){ 
     int current = 0; 
     for(int i = 0; i<4; i++){ 
      current = x; 
      System.out.println(current + ", "); 
      x = current + 2; 
     } 
    } 
} 

public class b{ 

    public static void main(String[] args) { 
     Runnable r1 = new Threads1(); 
     new Thread(r1).start(); 
     new Thread(r1).start(); 
    } 
} 

ВЫВОД:

0, 2, 0, 4, 6, 2, 4, 6 

Этот код использует внутренний класс под названием "Бегун":

public class Threads1 { 
    int x = 0; 
    public class Runner implements Runnable { 
     public void run(){ 
      int current = 0; 
      for(int i = 0; i<4;i++){ 
       current = x; 
       System.out.println(current + ", "); 
       x = current + 2; 
      } 
     } 
    } 

    public static void main(String[] args) { 
     new Threads1().go(); 
    } 

    public void go(){ 
     Runnable r1 = new Runner(); 
     new Thread(r1).start(); 
     new Thread(r1).start(); 
    } 
} 

ВЫВОД: (0, 2, 4, 4, 6, 8, 10, 6,) или (0, 2, 4, 6, 8, 10, 12, 14,)

Я узнал, что когда создаются два потока, они работают на своих собственных стеках, что означает, что они не разделяют ничего друг с другом, т.е. вывод (0, 2, 0, 4, 6, 2, 4, 6) может быть от (T1 , Т1, Т2, Т1, Т1, Т2, Т2, Т2), где Т1 и Т2 резьба 1 и 2. Автор

Однако, когда я использовал run() во внутреннем классе, оба потока разделяет переменную Current друг с другом , Например, выход (0, 2, 4, 4, 6, 8, 10, 6,) может быть от (T1, T1, T1, T2, T2, T2, T2, T1). Как вы можете видеть, на выходе есть double a 4, что означает, что thread1 передал его значение thread2. Почему это так?

ответ

3

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

В первом примере поле x кэшируется, как если бы оно было локальной переменной. Нет никакой гарантии, что это поведение произойдет в другой версии JVM или после компиляции кода.

Во втором случае у вас есть дополнительный уровень косвенности, что означает, что JIT с меньшей вероятностью оптимизирует доступ x к локальной переменной. Однако снова тонкие изменения могли видеть другое поведение.

0

Поскольку x является общим, он находится в содержащем классе.

+0

Я просто попробовал, на первый взгляд, даже если метод main() в том же классе ..Я получаю одинаковые результаты – user2985842

0

В первом случае x является членом класса Threads1, но Threads1 конкретизируется в индивидуальном порядке b CLAS и, таким образом, каждый поток получает свой собственный x. Во втором случае x является членом вашей внешней Threads1, и, таким образом, создается только один экземпляр x.

1

they work on there own stacks which means they share nothing with eachother

Это неправильно. В потоках есть другой стек, но они разделяют кучу (то есть память, где все экземпляры объекта и их переменные-члены, только функциональные переменные лежат в стеке) и int x существует только один раз в куче, поскольку вы создаете только один Threads1 объект, и оба Runnable s разделяют это

вы должны двигаться int x к Runner класса и создать новый объект Runner для каждого потока.

when i used run() in inner class both thread shares "Current" variable with eachother

также неправильно, они фактически делят переменную int x, как уже объяснялось. current уникален для каждой темы

+0

хорошо, если он разделяет кучу, то в первом случае, почему он не делится значением x? – user2985842

+0

логически они должны делиться х, но посмотрите на ответ Питера Лоури, объяснив это – x4rf41

Смежные вопросы