Есть простой глупый вопрос, который беспокоит меня и приводит в голову несколько аргументов. Я хочу развеять все сомнения по поводу нижеприведенных вопросов.
class Clstest{
public static String testStaticMethod(String inFileStr) {
// section 0
// section 1
// do something with inFileStr
// section 2
// section 3
return inFileStr;
}
}
Предположим, есть пять потоков, каждый из которых выполняет вызов Clstest.testStaticMethod("arg-n")
одновременно.
Звонки потока 1 Clstest.testStaticMethod("arg-1")
.
Когда поток 1 находится в разделе 1, вызывает поток 2 Clstest.testStaticMethod("arg-2")
.
Тогда что будет с потоком 1? Он перейдет в состояние сна?
Когда поток 1 получит шанс, он возобновит выполнение из раздела 1, где он был приостановлен?
Как это происходит, когда один Clstest.testStaticMethod
и тот же Clstest.testStaticMethod
объект используется всеми пятью потоками?
Есть ли возможность обменять inFileStr
отправленные несколькими потоками?
источник
Ответы:
Ответ Ханса Пассанта хорош. Но я подумал, что попытаюсь объяснить на более простом уровне для всех, кто сталкивается с этим и плохо знаком с Java. Поехали..
Память в java делится на два типа - кучу и стеки. Куча - это место, где живут все объекты, а стеки - это место, где потоки выполняют свою работу. Каждый поток имеет свой собственный стек и не может получить доступ к стекам друг друга. У каждого потока также есть указатель на код, который указывает на бит кода, который они выполняют в данный момент.
Когда поток запускает новый метод, он сохраняет аргументы и локальные переменные этого метода в своем собственном стеке. Некоторые из этих значений могут быть указателями на объекты в куче. Если два потока запускают один и тот же метод одновременно, они оба будут иметь указатели кода, указывающие на этот метод, и будут иметь свои собственные копии аргументов и локальных переменных в своих стеках. Они будут мешать друг другу только в том случае, если объекты в их стопках указывают на одни и те же объекты в куче. В этом случае может случиться всякое. Но, как указывает Ханс, строки неизменяемы (не могут быть изменены), поэтому мы в безопасности, если это единственный объект, который «совместно используется».
Один и тот же метод может выполнять так много потоков. Они могут не работать одновременно - это зависит от количества ядер на вашем компьютере, поскольку JVM отображает потоки Java в потоки ОС, которые запланированы на аппаратные потоки. Поэтому у вас мало контроля над чередованием этих потоков без использования сложных механизмов синхронизации .
Обратите внимание, что сон - это то, что поток делает сам с собой.
источник
Нет, выполнение потока не влияет на другие потоки, если они намеренно не синхронизируются друг с другом. Если у вас более одного ядра процессора, как у всех последних машин, эти потоки, вероятно, будут выполняться в одно и то же время. Это становится немного менее вероятным, когда вы запускаете 5 потоков, поскольку на вашей машине может не хватать ядер. Операционная система вынуждена выбирать между ними, давая каждому время для работы. Работа планировщика потоков. Тогда поток не будет находиться в «спящем» состоянии, он просто приостановлен и ждет, пока планировщик потоков не даст ему возможность запуститься. Он возобновится с того места, где он был прерван планировщиком.
Такой возможности нет, потоки имеют свой собственный стек, поэтому любой аргумент метода и локальная переменная будут уникальными для каждого потока. Кроме того, использование строки гарантирует, что эти потоки не могут мешать друг другу, поскольку строки неизменяемы.
Нет такой гарантии, если аргумент является ссылкой на другой вид изменяемого объекта. Или если сам метод использует статические переменные или ссылки на объекты в куче. Синхронизация требуется, когда поток изменяет объект, а другой поток читает его. Замок ключевое слово в языке С # это шаблонный способ реализовать такую необходимую синхронизацию. Тот факт, что метод статичен , не означает, что такая синхронизация никогда не требуется. Это менее вероятно, поскольку вам не нужно беспокоиться о потоках, обращающихся к одному и тому же объекту (разделяя его ).
источник