1. Создайте тему
Существует два способа создания потоков в Java: с помощью класса Thread и с помощью интерфейса Runnable. При использовании интерфейса Runnable вам необходимо создать экземпляр Thread. Таким образом, независимо от того, создаете ли вы поток через класс Thread или интерфейс Runnable, вы должны создать экземпляр класса Thread или его подкласса. Конструктор темы:
Способ 1: наследовать класс Thread и переопределить метод run.
}
}
класс Demo расширяет Thread{
общественный недействительный запуск () {
for(int i=0;i<60;i++){
System.out.println(Thread.currentThread().getName()+i);
}
}
}
Точно так же, как люди рождаются, стареют, болеют и умирают, потоки также должны пройти через четыре разных состояния: запуск (ожидание), запуск, зависание и остановка. Этими четырьмя состояниями можно управлять с помощью методов класса Thread. Ниже приведены методы, относящиеся к этим четырем состояниям в классе Thread.
Поток не выполняет код метода run сразу после его установления, а находится в состоянии ожидания. Когда поток находится в состоянии ожидания, вы можете установить различные атрибуты потока с помощью методов класса Thread, такие как приоритет потока (setPriority), имя потока (setName) и тип потока (setDaemon).
Когда вызывается метод start, поток начинает выполнение кода в методе run. Поток переходит в рабочее состояние. Вы можете использовать метод isAlive класса Thread, чтобы определить, запущен ли поток. Когда поток находится в состоянии выполнения, isAlive возвращает true. Когда isAlive возвращает false, поток может находиться в состоянии ожидания или в состоянии остановки. Следующий код демонстрирует переключение между тремя состояниями создания потока, запуска и остановки, а также выводит соответствующее возвращаемое значение isAlive.
Как только поток начнет выполнять метод run, он не завершится до тех пор, пока метод run не будет завершен. Однако во время выполнения потока есть два метода, которые можно использовать для временной остановки выполнения потока. Эти два метода — приостановка и сон. После использования suspend для приостановки потока вы можете разбудить его с помощью метода возобновления. После использования режима сна для перевода потока в режим сна поток может находиться в состоянии готовности только по истечении установленного времени (после завершения режима сна поток может не выполняться немедленно, а только переходит в состояние готовности, ожидая, пока система запланирует выполнение графика). .
При использовании метода сна следует учитывать два момента:
1. Метод сна имеет две перегруженные формы. Одна из перегруженных форм может задавать не только миллисекунды, но и наносекунды (1 000 000 наносекунд равны 1 миллисекунде). Однако виртуальная машина Java на большинстве платформ операционных систем не имеет точности до наносекунд. Поэтому, если для режима сна установлены наносекунды, виртуальная машина Java будет использовать миллисекунду, наиболее близкую к этому значению.
2. При использовании метода сна необходимо использовать броски или try{...}catch{...}. Поскольку метод run не может использовать throws, вы можете использовать только try{...}catch{...}. Когда поток находится в спящем режиме и для прерывания потока используется метод прерывания, режим сна выдает InterruptedException. Метод сна определяется следующим образом:
Есть три способа завершить поток.
1. Используйте флаг выхода, чтобы обеспечить нормальное завершение потока, то есть поток завершается после завершения метода запуска.
2. Используйте метод stop для принудительного завершения потока (этот метод не рекомендуется, поскольку остановка, как и приостановка и возобновление, также может привести к непредсказуемым результатам).
3. Используйте метод прерывания, чтобы прервать поток.
1. Завершите поток, используя флаг выхода.
Когда метод run будет выполнен, поток завершится. Но иногда метод run никогда не заканчивается. Например, потоки используются в серверных программах для мониторинга клиентских запросов или других задач, требующих циклической обработки. В этом случае эти задачи обычно помещаются в цикл, например цикл while. Если вы хотите, чтобы цикл выполнялся вечно, вы можете использовать while(true){...} для его обработки. Но если вы хотите, чтобы цикл while завершился при определенном условии, самый прямой способ — установить флаг логического типа и установить для этого флага значение true или false, чтобы контролировать, будет ли завершаться цикл while. Ниже приведен пример завершения потока с использованием флага выхода.
Функция метода соединения заключается в том, чтобы превратить асинхронные потоки выполнения в синхронные. То есть, когда вызывается метод запуска экземпляра потока, этот метод немедленно возвращает значение. Если вам нужно использовать значение, вычисленное этим потоком после вызова метода запуска, вы должны использовать метод соединения. Если вы не используете метод соединения, нет никакой гарантии, что при выполнении оператора, следующего за методом start, поток будет выполнен. После использования метода соединения программа не продолжит выполнение до тех пор, пока этот поток не завершится. Следующий код демонстрирует использование соединения.
3. Проблемы многопоточной безопасности
Причина проблемы: когда несколько операторов работают в одном потоке и совместно используют данные, один поток выполняет только часть нескольких операторов. До завершения выполнения в выполнении участвует другой поток, что приводит к ошибкам общих данных.
Решение. Для нескольких операторов, которые работают с общими данными, может выполняться только один поток. В процессе выполнения другие потоки не будут выполняться.
Синхронный блок кода:
}
}
}
}
общественный недействительный запуск () {
пока (правда) {
продажаБилет();
}
}
}
Связь между потоками
х=(х+1)%2;
}
}
}).начинать();
новый поток (новый Runnable() {
общественный недействительный запуск () {
пока (правда) {
п.получить();
}
}
}).начинать();
}
}
/*
Чжан Сан....Мужчина Чжан Сан....Мужчина
Лили....нв
лили....мужчина Чжан Сан....nv
Лили....мужчина
*/
}
}
}).начинать();
новый поток (новый Runnable() {
общественный недействительный запуск () {
пока (правда) {
синхронизировано (р) {
п.получить();
}
}
}
}).начинать();
}
}
/*
Лили....нв
Лили....нв
Лили....нв
Лили....нв
Лили....нв
Лили....нв
Чжан Сан....Мужчина Чжан Сан....Мужчина Чжан Сан....Мужчина Чжан Сан....Мужчина
*/
}
}
}).начинать();
новый поток (новый Runnable() {
общественный недействительный запуск () {
пока (правда) {
синхронизировано (р) {
если(!флаги)
пытаться {
п.ожидание();
} catch (InterruptedException e) {
// TODO Автоматически сгенерированный блок catch
е.printStackTrace();
};
п.получить();
флаги = ложь;
p.notifyAll();
}
}
}
}).начинать();
}
}
}
окончательные товары g = новые товары();
новый поток (новый Runnable() {
общественный недействительный запуск () {
пока (правда) {
g.produce("товар");
}
}
}).начинать();
новый поток (новый Runnable() {
общественный недействительный запуск () {
в то время как (правда) {
г.потреблять();
}
}
}).начинать();
}
}
}
окончательные товары g = новые товары();
новый поток (новый Runnable() {
общественный недействительный запуск () {
в то время как (правда) {
g.produce("товар");
}
}
},"Продюсер №1").start();
новый поток (новый Runnable() {
общественный недействительный запуск () {
в то время как (правда) {
g.produce("товар");
}
}
},"Производитель №2").start();
новый поток (новый Runnable() {
общественный недействительный запуск () {
в то время как (правда) {
г.потребление();
}
}
},"Потребитель №1").start();
новый поток (новый Runnable() {
общественный недействительный запуск () {
в то время как (правда) {
г.потребление();
}
}
},"Потребитель №2").start();
}
}
/*
Потребитель №2 потреблял ******номер товара: 48049
Производитель One произвел....Артикульный номер: 48050
Потребитель №1 потреблял ******номер товара: 48050
Производитель One произвел....Артикульный номер: 48051
Потребитель №2 потреблял ******номер товара: 48051
Производитель №2 выпустил....Артикульный номер: 48052
Потребитель №2 потреблял ******номер товара: 48052
Производитель One произвел....Артикульный номер: 48053
Потребитель №1 потреблял ******номер товара: 48053
Производитель One произвел....Артикульный номер: 48054
Потребитель №2 потреблял ******номер товара: 48054
Производитель №2 выпустил....Артикульный номер: 48055
Потребитель №2 потреблял ******номер товара: 48055
*/