Начал потока:
1. Описание разницы между start () и run ()
start (): его функция - запустить новый поток, а новый поток выполнит соответствующий метод run (). start () не может быть вызван неоднократно.
run (): run () можно называть многократно, как обычные методы участника. Если вы вызовите run () отдельно, run () будет выполнен в текущем потоке, а новый поток не будет запущен!
Ниже приведен код для объяснения.
класс mythread extends thread {public void run () {...}}; mythread mythread = new mythread (); mythread.start () запускает новый поток и запускает метод run () в новом потоке.
Mythread.run () будет запускать метод run () непосредственно в текущем потоке и не запустит новый поток для run ().
2. Пример разницы между start () и run ()
Ниже продемонстрируйте разницу между ними с простым примером. Исходный код заключается в следующем:
// demo.java's Source Code Class Mythread Extends Thread {public Mythread (String name) {super (name); } public void run () {System.out.println (thread.currentThread (). getName ()+"работает"); }}; открытый класс Demo {public static void main (string [] args) {thread mythread = new mythread ("mythread"); System.out.println (thread.currentThread (). GetName ()+"Call Mythread.run ()"); mythread.run (); System.out.println (thread.currentThread (). GetName ()+"Call Mythread.start ()"); mythread.start (); }} Результаты работы:
Главный звонок mythread.run () main - это running -main call mithread.start () Mythread работает
Результаты Описание:
(1) Thread.currentThread (). GetName () используется для получения имени «Текущий поток». Текущий поток относится к потоку, который должен выполняться в процессоре.
(2) mythread.run () называется «Main Thread Main», а метод run () работает непосредственно на «Main Thread Main».
(3) mythread.start () запустит «нить Mythread». После того, как «нить Mythread» запускается, будет вызван метод run (); В настоящее время метод run () запускается на «Thread Mythread».
Потоки перерывы и терминации
1. РАЗРЕШЕНИЕ РАЗРЕШЕНИЯ: Enterrupt ()
Функция Enterrupt () состоит в том, чтобы прервать поток.
Этот поток может прерываться; Когда другие потоки вызывают метод Enterrupt () этого потока, разрешение будет проверено через checkaccess (). Это может вызвать исключение Security Exception.
Если поток находится в состоянии блокировки: вызовы wait (), подождите (долго) или подождите (длинный, int) потока, превратит его в ожидание (блокирующее) состояние или вызов join (), соединение (длинное), присоединяйтесь (длинный, int), сон (длинный), сон (длинный, int) нить также превратит его в блокирующее состояние. Если поток вызывает метод Enterrupt () при блокировании, его «состояние прерывания» будет очищено, и будет получено прерывание. Например, поток входит в состояние блокировки через wait (), и поток прерывается Enterrupt (); Calling enterrupt () немедленно установит флаг прерывания потока на «true», но, поскольку поток находится в состоянии блокировки, «флаг прерывания» будет немедленно очищен в «False», и будет сгенерировано прерывание.
Если поток заблокирован в селекторе селектора, то когда он прерывается Enterrupt (); Флаг прерывания потока установлен на True и будет немедленно возвращен из операции выбора.
Если он не принадлежит к ситуации, упомянутой выше, то, когда поток прерывается через Enterrupt (), его флаг прерывания будет установлен на «true».
Прерывание «закрытого потока» не вызовет никакой работы.
2. Завершение потока
Рекомендуется не использовать методы STOP () и SUSARDEND () в потоке.
Далее я сначала обсудим метод завершения потоков в «состоянии блокировки» и «управляемого состояния» соответственно, а затем суммирую общий метод.
1. Завершение нити в «состоянии блокировки»
Обычно мы заканчиваем нить в «состоянии блокировки» путем «прерывания».
Когда нить входит в состояние блокировки из -за того, что его называют Sleep (), wait (), join () и другие методы; Если в настоящее время вызывается прерывание потока, отметка прерывания потока устанавливается на TRUE. Поскольку он находится в состоянии блокировки, флаг прерываний будет очищен, и генерируется исключение прерванного эктриэсипции. Установка прерванного эктриэкцепции до тех пор, пока оно не станет подходящим, может завершить поток, в форме следующим образом:
@OverridePublic void run () {try {while (true) {// выполнить задачу ...}} catch (прерывание EXCEPTION IE) {// Из -за исключения прерывания, выйти из цикла (true) и поток заканчивается! }} ПРИМЕЧАНИЕ. Когда задача непрерывно выполняется в то время как (true), когда поток находится в состоянии блокировки, вызов Entreprupt () потока генерирует прерывание прерывания. Прерывавший захват находится на улице, в то время как (истинно), тем самым выходя из петли (истинного)!
ПРИМЕЧАНИЕ. Захват прерывавшего эклеста обычно помещается за пределы (истинного) тела цикла, так что цикл (истинный) выходит при выходе при генерации исключения. В противном случае, если прерванное эктрипений находится внутри (истинного) тела цикла, требуется дополнительное добавление и обработка выхода. Форма заключается в следующем:
@OverridePublic void run () {while (true) {try {// execute task ...} catch (прерванное экзритинг, т.е. // Когда поток генерирует исключение прерывавшего эктри, а (true) может продолжать работать! Необходимо вручную выходить из перерыва; }}} ПРИМЕЧАНИЕ. Вышеупомянутое исключение прерванного экспрессии попадает в WHLE (True). Когда генерируется исключение прерванного эктриэкцепции, оно не обрабатывается уловкой и все еще находится в теле (истинном) петле; Чтобы выйти из тела цикла Whance (истина), необходимо выполнить дополнительную операцию выхода из выхода (истинного).
2. Завершение потока в «Государстве управления»
Обычно мы заканчиваем ветку в «управляемом состоянии», «маркировка». Среди них это включает в себя «флаг прерывания» и «добавить дополнительный флаг».
(1) Завершить нить через «Флаг прерывания».
Форма заключается в следующем:
@OverridePublic void run () {while (! IsErengreting ()) {// Выполнить задачу ...}} Описание: isErengroupted () определяет, является ли флаг прерывания потока правдой. Когда поток находится в состоянии управления, и мы должны его прекратить; Метод прерывания потока () может быть вызван, и флаг прерывания потока помечен правда, то есть isErengrupted () вернет true. На данный момент, петля будет выходить из строя.
Примечание: Enterrupt () не прекращает потоки в «Готовом состоянии»! Он устанавливает флаг прерывания потока на True.
(2) Пропустите «Добавить дополнительные оценки».
Форма заключается в следующем:
Private volatile Boolean Flag = true; Protected void stoptask () {flag = false;}@overridePublic void run () {while (flag) {// execute task ...}} Описание: В потоке есть тег флага, и его значение по умолчанию верно; И мы предоставляем stoptask (), чтобы установить тег флага. Когда нам нужно прекратить поток, вызов метода stoptask () потока может привести к выходу из потока поток.
Примечание. Флаг определяется как летучий тип, чтобы обеспечить видимость флага. То есть после того, как другие потоки изменяют флаг через stoptask (), этот поток может увидеть измененное значение флага.
Комплексные методы прекращения потоков в «состоянии блокировки» и «управляемого состояния», более распространенные потоки прекращения следующие:
@OverridePublic void run () {try {// 1. isErengrupted () гарантирует, что поток будет прекращен, если прерывание помечено true. while (! isErengeTrupted ()) {// Выполнить задачу ...}} catch (прерывание Exception IE) {// 2. Исключение прерывания. }} 3. Пример завершающего потока
Enterrupt () часто используется для прекращения потока «состояния блокировки». Обратитесь к следующему примеру:
// demo1.java исходный код класс MyThread Extends extends {public mythread (string name) {super (name); } @Override public void run () {try {int i = 0; while (! isErengeTed ()) {Thread.sleep (100); // Сон 100 мс i ++; System.out.println (think.currentThread (). GetName ()+"("+this.getState ()+") loop"+i); }} catch (прерывание Exception e) {System.out.println (thread.currentThread (). getName ()+"("+this.getState ()+") catch recturtException."); } / // Создать новую "Thread T1" System.out.println (t1.getName ()+"("+t1.getState ()+") является новым."); t1.start (); // запустить "Thread T1" System.out.println (t1.getName ()+"("+t1.getState ()+") запускается."); // Основная нить спит на 300 мс, а затем основной поток отправляет инструкцию «прерывание» в T1. Thread.sleep (300); T1.Enterrupt (); System.out.println (t1.getName ()+"("+t1.getState ()+") прерывается."); // Основная поток спит на 300 мс, а затем проверяет состояние T1. Thread.sleep (300); System.out.println (t1.getName ()+"("+t1.getState ()+") прерывается сейчас."); } catch (прерванное искусство e) {e.printstacktrace (); }}} Результаты работы:
T1 (новый) is new.t1 (runnable) запускается. T1 (runnable) Loop 1T1 (Runnable) Loop 2T1 (Timed_Waiting) прерывается. Т1 (Runnable) Catch EtrepteDexception.t1 (завершен) сейчас прерывается.
Результаты Описание:
(1) Основной поток Main создает поток T1 через New Mythread («T1»), а затем запускает нить T1 до t1.start ().
(2) После начала T1 его флаг прерывания будет проверяться непрерывно. Если флаг прерывания «ложный», он будет спать на 100 мс.
(3) После того, как T1 спит, он переключится на основную резьбу Main; Когда основной поток снова запускается, T1.interrupt () будет выполнен для прерывания потока T1. После того, как T1 получает инструкцию прерывания, флаг прерывания T1 будет установлен на «FALSE», и будет брошено прерывание. В методе run () T1 это исключение, пойманное вне тела петли, пока; Поэтому петля прекращается.
Мы внесли небольшую модификацию к вышеуказанному результату и перенесли кодовый блок, который поймал исключение прерванного эктриэкцепции в методе run () в корпус цикла while.
// demo2.java исходный код класс MyThread Extends Thread {public Mythread (String name) {super (name); } @Override public void run () {int i = 0; while (! isErengtted ()) {try {thread.sleep (100); // Sleep для 100 мс} catch (прерывание Exception IE) {System.out.println (Thread.currentThread (). GetName ()+"("+this.getState ()+") Catch OverruptEdException."); } i ++; System.out.println (think.currentThread (). GetName ()+"("+this.getState ()+") loop"+i); }}} открытый класс demo2 {public static void main (string [] args) {try {thread t1 = new MyThread ("t1"); // Создать новую "Thread T1" System.out.println (t1.getName ()+"("+t1.getState ()+") является новым."); t1.start (); // запустить "Thread T1" System.out.println (t1.getName ()+"("+t1.getState ()+") запускается."); // Основная нить спит на 300 мс, а затем основной поток отправляет инструкцию «прерывание» в T1. Thread.sleep (300); T1.Enterrupt (); System.out.println (t1.getName ()+"("+t1.getState ()+") прерывается."); // Основная поток спит на 300 мс, а затем проверяет состояние T1. Thread.sleep (300); System.out.println (t1.getName ()+"("+t1.getState ()+") прерывается сейчас."); } catch (прерванное искусство e) {e.printstacktrace (); }}} Результаты работы:
T1 (новый) is new.t1 (runnable) запускается. T1 (Runnable) Loop 1T1 (Runnable) Loop 2T1 (Timed_Waiting) прерывается. T1 (Runnable) Catch InterruptEdexception.t1 (Runnable) Loop 3T1 (Runnable) LOOP 4T1 (Runnable) LOOP 5T1 (TIMED_WATINTIONTIONTIONTIONTIONTIONTIONTION) ISTINTING) (Запустить) Loop 6t1 (Runnable) Loop 7t1 (Runnable) Loop 8t1 (Runnable) Loop 9 ...
Результаты Описание:
Программа вошла в мертвую петлю!
Почему это происходит? Это связано с тем, что T1 прерывается Enterrupt (), когда он «ожидает (блокирующего) состояния». В настоящее время флаг прерывания очищается [который прерывается () вернет false], и исключение прерываноэкспрессии добавлено [это исключение попадает в корпус петли]. Поэтому T1 естественным образом войдет в порочный цикл.
Чтобы решить эту проблему, нам нужно дополнительную обработку, чтобы выйти из петли while, когда поймали исключение. Например, добавление перерыва или возврата в Mythread Catch (прерывание) может решить проблему.
Вот пример потока, который завершает «состояние состояния» путем «добавления дополнительных тегов»:
// demo3. Java's Source Code Class Mythread Extends Thread {private volatile Boolean flag = true; public void stoptask () {flag = false; } public mythread (string name) {super (name); } @Override public void run () {synchronized (this) {try {int i = 0; while (flag) {thread.sleep (100); // Сон 100 мс i ++; System.out.println (think.currentThread (). GetName ()+"("+this.getState ()+") loop"+i); }} catch (прерывание Exception IE) {System.out.println (thread.currentThread (). getName ()+"("+this.getState ()+") catch recturtException."); }} / // Создать новую "Thread T1" System.out.println (t1.getName ())+"("+t1.getState ()+") является новым."); t1.start (); // запустить "Thread T1" System.out.println (t1.getName ()+"("+t1.getState ()+") запускается."); // Основная нить спит на 300 мс, а затем основной поток отправляет инструкцию «прерывание» в T1. Thread.sleep (300); t1.stoptask (); System.out.println (t1.getName ()+"("+t1.getState ()+") прерывается."); // Основная поток спит на 300 мс, а затем проверяет состояние T1. Thread.sleep (300); System.out.println (t1.getName ()+"("+t1.getState ()+") прерывается сейчас."); } catch (прерванное искусство e) {e.printstacktrace (); }}} Результаты работы:
T1 (новый) is new.t1 (runnable) запускается. T1 (runnable) Цикл 1T1 (Runnable) Loop 2T1 (Timed_Waiting) прерывается. Т1 (бегающий) цикл 3T1 (завершен) теперь прерывается.