1. присоединиться к теме :
Во время выполнения потока иногда вы хотите, чтобы сначала выполнялся другой поток, например, разделение большой проблемы на множество мелких проблем, назначение потоков каждой маленькой проблеме, но после того, как все небольшие проблемы будут обработаны, позвольте основному потоку выполнять дальнейшие операции. В это время мы можем вызвать метод join() других потоков в основном потоке, чтобы заблокировать вызывающий поток (в данном случае основной поток).
Пример кода:
Скопируйте код кода следующим образом:
пакет org.frzh.thread;
общественный класс JoinThread расширяет Thread {
//Предоставляем параметризованный конструктор для установки имени потока
public JoinThread (имя строки) {
супер(имя);
}
общественный недействительный запуск () {
для (int я = 0; я <100; я++) {
System.out.println(getName() + " " + i);
}
}
public static void main(String[] args) {
//Запускаем дочерний поток
new JoinThread("новый поток").start();
для (int я = 0; я <100; я++) {
если (я == 20) {
JoinThread jt = new JoinThread("поток, который нужно объединить");
jt.start();
//Основной поток вызывает метод соединения потока jt, затем основной поток должен дождаться завершения выполнения jt, прежде чем он сможет выполнить
пытаться {
jt.join();
} catch (InterruptedException e) {
// TODO Автоматически сгенерированный блок catch
е.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " " +i);
}
}
}
Первоначально было три набора потоков (два подпотока и один основной поток). Когда i=20, основной поток блокируется и должен ждать, пока «присоединенный поток» не будет выполнен, прежде чем он сможет выполниться, поэтому существует после этого выполняются только два потока.
Три перегруженные формы метода join():
join(): дождитесь завершения выполнения присоединенного потока;
join(long millis): максимальное время ожидания выполнения присоединенного потока составляет миллисекунды. После этого, даже если присоединенный поток еще не завершил выполнение, он больше не будет ждать;
join(long millis, int nanos): максимальное время ожидания выполнения присоединенного потока составляет миллис миллисекунды + нано микросекунды. (Этот метод в принципе бесполезен).
2: Фоновая тема :
Существует поток, который работает в фоновом режиме, и его задача — обслуживать другие потоки. Этот поток называется «фоновым потоком», «потоком демона» или «потоком эльфов». Когда все потоки переднего плана завершатся, фоновый поток автоматически завершится.
Пример кода:
Скопируйте код кода следующим образом:
пакет org.frzh.thread;
общественный класс DaemonThread расширяет Thread {
общественный недействительный запуск () {
для (int я = 0; я <1000; я++) {
System.out.println(getName() + " " +i);
}
}
public static void main(String[] args) {
DaemonThread dt = новый DaemonThread();
//Установим этот поток как фоновый поток
dt.setDaemon(истина);
дт.старт();
для (int я = 0; я <10; я++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
//Поток переднего плана заканчивается, затем завершается и фоновый поток dt, поэтому он не будет выполнять 999
}
}
Основной поток по умолчанию является потоком переднего плана, подпотоки, созданные потоком переднего плана, по умолчанию являются потоком переднего плана, а подпотоки, созданные фоновым потоком, по умолчанию являются фоновым потоком.
3. Сон потока (сон):
Предыдущий метод соединения позволяет вызывающему потоку дождаться завершения выполнения присоединенного потока, прежде чем продолжить, в то время как метод Sleep() позволяет вызывающему потоку блокироваться на определенный период времени, прежде чем снова войти в состояние готовности и ожидать завершения. запланировано. Поэтому его часто используют для приостановки выполнения программы.
Пример кода:
Скопируйте код кода следующим образом:
пакет org.frzh.thread;
импортировать java.util.Date;
общественный класс SleepThread {
public static void main(String[] args) {
для (int я = 0; я <10; я++) {
System.out.println("Текущее время: " + новая дата());
пытаться {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Автоматически сгенерированный блок catch
е.printStackTrace();
}
}
}
}
Два метода перегрузки метода Sleep():
static void Sleep (длинный миллис): позволяет текущему потоку приостановиться на миллимиллисекунды и войти в состояние блокировки. На этот метод влияет точность и аккуратность системных таймеров и планировщиков потоков.
static void Sleep (long millis, int nanos): пауза миллисекунды + наномикросекунды и вход в состояние блокировки. На это также влияет точность и точность системного таймера и планировщика потоков. В принципе не нужен.
4. Выход нити :
Метод yield() чем-то похож на метод сна. Он также может приостанавливать текущий поток, но не блокирует поток, а просто переводит его в состояние готовности (обратите внимание, что это не состояние блокировки). Метод yield() дает шанс на выполнение только потокам с тем же или более высоким приоритетом, поэтому поток может быть перепланирован обратно для продолжения выполнения после вызова этого метода.
Пример кода:
Скопируйте код кода следующим образом:
пакет org.frzh.thread;
общественный класс YieldThread расширяет Thread {
общественный YieldThread() {
}
public YieldThread (имя строки) {
супер(имя);
}
общественный недействительный запуск () {
для (int я = 0; я <100; я++) {
System.out.println(getName() + " " +i);
если (я == 20) {
//Текущий поток дает результат
Thread.yield();
}
}
}
public static void main(String[] args) {
//Запускаем два параллельных потока
YieldThread yt1 = новый YieldThread («Дополнительно»);
//Установим yt1 как наивысший приоритет
yt1.setPriority(Thread.MAX_PRIORITY);
yt1.start();
YieldThread yt2 = новый YieldThread("низкий уровень");
yt2.setPriority(Thread.MIN_PRIORITY);
yt2.start();
/*
* Если приоритет для потока не установлен, приоритет двух потоков один и тот же, поэтому два потока будут выполняться поочередно, а при вызове выходного сигнала будет выполняться другой поток;
* Однако после установки вышеуказанных приоритетов для двух потоков соответственно только начинается выполнение расширенного потока. Когда i = 20, вызывается метод доходности, но только потому, что метод доходности.
* Предоставьте возможность выполнения потокам с тем же или более высоким приоритетом, чтобы поток высокого уровня все еще выполнялся в это время и не был передан потокам низкого уровня.
*/
}
}
5: Измените приоритет потока :
Это относительно просто: просто вызовите метод экземпляра setPriority(int Priority). Каждый поток по умолчанию имеет тот же приоритет, что и его родительский поток, а основной поток по умолчанию имеет обычный приоритет (5). Java предоставляет приоритеты от 1 до 10, а также можно использовать три статические константы:
MAX_PRIORITY:10
MIN_PRIORITY:1
NORM_PRIORITY:5
Примечание. Хотя Java предоставляет 10 приоритетов, разные системы поддерживают разные приоритеты, поэтому старайтесь избегать прямого использования чисел от 1 до 10 и используйте статические константы, чтобы обеспечить хорошую переносимость.