Анализ и обдумывание вопроса на собеседовании по Java

интервью Java

Пожалуйста, указывайте первоисточник при перепечатке, спасибо!

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

Тема следующая:

public class TestSync2 implements Runnable {
	int b = 100;          

	synchronized void m1() throws InterruptedException {
		b = 1000;
		Thread.sleep(500); //6
		System.out.println("b=" + b);
	}

	synchronized void m2() throws InterruptedException {
		Thread.sleep(250); //5
		b = 2000;
	}

	public static void main(String[] args) throws InterruptedException {
		TestSync2 tt = new TestSync2();
		Thread t = new Thread(tt);  //1
		t.start(); //2

		tt.m2(); //3
		System.out.println("main thread b=" + tt.b); //4
	}

	@Override
	public void run() {
		try {
			m1();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

}

Результат этой программы?

Вывод программы

main thread b=2000
b=1000
或
main thread b=1000
b=1000

Исследуйте очки знаний

  • синхронизировать блокировку экземпляра.
  • Видимость памяти при параллелизме.

В java многопоточные программы наиболее сложны для понимания и отладки, и во многих случаях результаты выполнения выполняются не так, как мы себе представляли. Поэтому многопоточность в java особенно сложна.Я смутно помню, что когда я сдавал тест второго уровня по языку Си в колледже, какие в нем были вопросы?++ и многие другие символы приоритета используются для задания конечного вывода Я хочу проверить некоторые из этих вопросов. Вопросы приоритета во время выполнения и ассоциативности. Эта спина в порядке.Но многопоточность java еще нужно хорошо понимать, а спинка не приемлема.

Начнем с простого анализа:

В этой теме участвуют 2 потока (основной поток, основной поток, дочерний поток), а ключевые слова включают синхронизированный, Thread.sleep. Синхронизированное ключевое слово по-прежнему относительно сложно (иногда оно может быть не понято на месте, поэтому приведенная выше тема будет немного неправильно понята), его роль заключается в реализации потоков.Синхронизировать(Существует много способов добиться синхронизации потоков, это всего лишь один, а в следующей статье речь пойдет о других, вам нужно изучить некоторые реализации великого бога Дуга Ли), его работа заключается в блокировке кода, который необходимо быть синхронизированным, так что только один поток за раз может войти в синхронизированный блок (фактически пессимистическая стратегия), чтобы гарантировать, что поток помнит только о безопасности.

Использование общего ключевого слова синхронизировано
  • Указывает объект блокировки: заблокируйте заранее определенный объект для данного объекта, вам необходимо прожить список заданных объектов перед кодом синхронизации.
  • Воздействие непосредственно на метод экземпляра: это эквивалентно блокировке текущего экземпляра, и блокировка текущего экземпляра должна быть получена до ввода кода синхронизации.
  • Прямое действие на статические методы: эквивалентно блокировке текущего класса, причем блокировку текущего класса необходимо получить до ввода кода синхронизации.

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

возможные ошибки
  1. Из-за отсутствия понимания синхронизации, потому что много раз мы используем синхронизированный метод в нескольких потоках. Когда два потока вызывают два разных синхронизированных метода, это считается неуместным. Такое мышление неправильно понимается.Воздействие непосредственно на метод экземпляра: это эквивалентно блокировке текущего экземпляра, и блокировка текущего экземпляра должна быть получена до ввода кода синхронизации.
  2. Если кто-то вызывает синхронный метод. Другой не связан с вызовом обычных методов, и между ними нет ожидающих отношений.

Они полезны для последующего анализа.

Thread.sleep

Приостановить выполнение текущего потока (т. е. потока, вызывающего метод) на определенный период времени, давая другим потокам возможность продолжить выполнение, но не освобождая блокировку объекта. То есть, если есть синхронизированная синхронизация, другие потоки по-прежнему не могут получить доступ к общим данным. **Обратите внимание, что этот метод должен перехватывать исключения, что очень полезно для последующего анализа. Некоторые детали могут относиться к моемуСистемное обучение Java с высокой степенью параллелизма, вторая серия.

Процесс анализа

Java выполняется из основного метода.Как было сказано выше, есть два потока, но менять приоритет потока здесь бесполезно.Приоритет только тогда, когда две программы не были выполнены.Теперь этот код выполняется., основной основной поток был выполнен. Для переменной атрибута int b = 100 проблемы с видимостью нет из-за использования synchronized (и нет необходимости использовать объявление volatile) при выполнении1 шагКогда (Thread t = new Thread(tt); //1) поток находится в новом состоянии и еще не начал работать. при исполнении2 шагаКогда (t.start(); //2) Когда вызывается метод start, поток действительно запускается и переходит в состояние runnable, состояние runnable означает, что его можно выполнять и все готово, но это не значит, что он должен выполняться на процессоре. Реальное выполнение не зависит от планирования сервисного процессора. здесь при выполнении3 шагаБлокировка должна быть получена в первую очередь (поскольку для запуска необходимо вызвать собственный метод, и все будет готово после завершения использования, но это не означает, что она должна выполняться на процессоре. Будет ли она выполнена на самом деле, зависит от планирования сервисный процессор, а затем будет вызван метод run. , выполните метод m1). На самом деле не имеет значения, является ли Thread.sheep в двух синхронизированных методах фактически безразличным, считается, что это увеличит сложность путаницы. Когда выполняются 3 шага, дочерний поток фактически скоро готов, но из-за существования синхронизированного и одного и того же объекта дочернему потоку остается только ждать. Поскольку порядок выполнения в основном методе выполняется последовательно, он должен быть завершен после выполнения шага 3.4 шага, и поскольку 3 шага выполнены, дочерний поток может выполнить m1.Здесь возникает многопоточный вопрос, кто должен получить, так что если на первом этапе получения 4 основной поток b = 2000, если дочерний поток m1 получить, вероятно, b уже присвоено значение 1000 или еще не успели отойти от задание 4 выводит возможные результаты: основной поток b = 1000 или основной поток b = 2000, вот если6 шагов для удаленияТогда b=выполнение сначала и основной поток b=first не определены. Но из-за наличия 6 ступеней, несмотря ни на что, основная нить b= находится впереди, далее она равна 1000 или 2000 в зависимости от ситуации, а затем b=1000 фиксируется.

Некоторые рекомендации по многопоточности

  • Нитки тоже ценятся, поэтому рекомендуется использоватьПул потоков, пул потоков используется очень часто, и особенно важно подготовить его к совместному использованию позже, и необходимо знать, что делать.
  • Назовите поток.Когда онлайн-процессор высок, вам нужно использовать расширенный jstack.Очень удобно иметь имя.
  • В многопоточности нужно уделять особое внимание вопросам безопасности потоков, а также нужно понимать, какой jdk является потокобезопасным, а какой небезопасным, чтобы не возникало необъяснимых проблем при его использовании.

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

Некоторые советы по отладке для многопоточности

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

Анализ дампа потока и последующее содержимое потока будут по-прежнему анализироваться и публиковаться позже.


У меня есть еще одна статья, связанная с дорогами для новичков JVM.


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