2016-06-02 8 views
0

Я читал о том, как методы выполняются, и это то, что я понимаю: 1) Методы распределяются в области метода и поддерживается только одна копия, которая используется во всех экземплярах класса. 2) Когда метод вызывается из экземпляра затем текущего потока (однопоточный ENV) говорят, главное загружается, а затем стек загружается с помощью метода вызывается с помощью instance.eg:Как метод класса Java распределяется и выполняется в однопоточной и многопоточной среде?

main(String ags[]) 
{ 
    A a = new A(); 
    a.method(); 
} 
// code of method 
method() 
{ 
    for(int i=0;i<25;i++) 
    system.out.println(i); 
} 

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

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

//My run method for myRunnable 
run() 
{ 
    a.method(); 
} 

Thread one = new Thread(new myRunnable(a)); // object from above 
Thread two= new Thread(new myRunnable(a)); 

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

Как будет выполняться метод совместно используемого объекта в этом случае ?.

Благодаря

ответ

1

1) Методы выделяются память в области метода, и только одна копия поддерживается, который используется во всех экземпляров класса >>, что означает, что байт-код реализации метода только один за все экземпляров. А область памяти байт-кода метода отделена от кучи объекта.

Каждая нить имеет свой собственный стек, конечно, точно так же, как вы это объясняете.

+0

Да, но я не понял, что если оба потока загружают копию метода в свой собственный стек, значит, оба должны печатать последовательность из них, например, начиная с 1 до 25. Вместо этого вывод является общим, означает, что один поток запускает последовательность и идет до 5, затем два потока поднимаются оттуда и начинаются с 6 до некоторой точки, скажем 10, а затем начинается с 10. Как это происходит, если у них обоих есть собственный стек. –

+0

Нет, этого не должно быть. Как вы это заметили? – Thilo

+0

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

1

Если у вас есть несколько потоков, выполняющихся один и тот же метод того же объекта одновременно, то есть следующая ситуация:

  • локальные переменные хранятся в стеке каждого потока. Они не разделяются и не конфликтуют.

  • Экземпляр объекта (this) хранится в куче, а также во всех его полях (например, this.foo). Куча разделяется. Чтобы убедиться, что это работает правильно, вам необходимо применить механизмы синхронизации потоков, если это необходимо.

  • static поля также общий доступ и должны быть скоординированы, слишком

В вашем примере, i в цикле является локальной переменной. Оба потока будут печатать все числа в последовательности (но вывод двух потоков чередуется в неопределенном порядке).

+0

Да, ваше объяснение имеет смысл, но я не мог найти ни одного числа, повторяющегося в выводе. –

+1

@NitinSaxena Вы начали все темы? – glee8e

+0

Спасибо всем за ваши объяснения. –

0

Хорошо, вы заходите в комнату.

Кто-то вручает вам буфер обмена и карандаш и маркер доски, а затем сообщает, что вы начинаете следовать инструкциям, которые написаны на определенном плакате на стене.

На другой стене есть доска: это выглядит как электронная таблица с строками и столбцами, а также номерами и словами, записанными в ячейках.У вашего буфера обмена есть лист бумаги с большим количеством строк и столбцов, а некоторые цифры написаны на на некоторых ячейках карандаша.

В инструкциях рассказывается, как выполнить сложный расчет . Они говорят такие вещи, как:

... 
Step 37: Copy the number from B5 on the whiteboard into J2 on your 
     clipboard. 
Step 38: Add J2 through J7 on your clipboard, and write the result in J9. 
Step 39: If the result in J9 is greater than the value in whiteboard-C9, 
     then go back to step 22, otherwise, go on to step 40. 
Step 40: Erase whiteboard-C9, and then copy the value from clipboard-J9 
     into that location. 
... 

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

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

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

Это простейшее модели многопоточных вычислений: Плакаты на стене являются методами, интерактивной доской является кучей, люди нить, и ваших блокнотов ваших стек.

Это также примерно похоже на то, как научные/инженерные расчеты были выполнены , выполненные в индустриальную эпоху. Люди, которые делали такую ​​работу, были , называемые «компьютеры».

Если вы координируете все это, и пришло время добавить новую «нить» (т. Е. Когда новый волонтер входит в комнату), тогда вам нужно будет предоставить этому человеку свой собственный буфер обмена (стек), с его собственными начальными значениями (параметрами), но вы не даете новому человеку его собственный плакат (методы): вы просто указываете ее/его на одном из плакатов, которые уже на стене.