Наиболее полный анализ использования многопоточного использования Java. Если вы не провели углубленное исследование по механизму многопоточного чтения Java, то эта статья может помочь вам более тщательно понять принципы и методы использования многопоточного чтения Java.
1. Создайте потоку
В Java есть два способа создания потоков: использование класса потока и использование интерфейса запускающегося. При использовании запускаемого интерфейса вам необходимо создать экземпляр потока. Следовательно, независимо от того, устанавливаете ли вы поток через класс потока или на запускаемом интерфейсе, вы должны установить экземпляр класса потока или его подкласса. Конструктор потока:
Метод 1: Унаследовать класс потоков и перезаписать метод запуска
public Class Threaddemo1 {public static void main (string [] args) {demo d = new demo (); D.Start (); for (int i = 0; i <60; i ++) {System.out.println (thread.currentThread (). getName ()+i); }}} класс Demo Extends Thread {public void run () {for (int i = 0; i <60; i ++) {System.out.println (thread.currentThread (). getName ()+i); }}}Метод 2:
public Class threaddemo2 {public static void main (string [] args) {demo2 d = new demo2 (); Потока t = новый поток (d); t.start (); for (int x = 0; x <60; x ++) {System.out.println (thread.currentThread (). getName ()+x); }}} класс Demo2 реализует runnable {public void run () {for (int x = 0; x <60; x ++) {system.out.println (thread.currentThread (). getName ()+x); }}}2. Жизненный цикл потоков
Точно так же, как люди имеют рождение, старость, болезнь и смерть, темы также должны пройти через четыре разных состояния: запустите (подождите), беги, приостановка и остановка. Все четыре состояния можно контролировать методами в классе потока. Ниже приведен метод, связанный с этими четырьмя состояниями в классе потока.
// начало потока
publicvoid start ();
publicvoid run ();
// приостановка и пробуждение потоков
publicvoid resume (); // не рекомендуется использовать
publicvoid suspend (); // не рекомендуется использовать
Publicstaticvoid Sleep (Long Millis);
Publicstaticvoid Sleep (Long Millis, int nanos);
// Завершение потока
Publicvoid Stop (); // не рекомендуется использовать
publicvoid enterrupt ();
// Получить состояние потока
PublicBoolean Isalive ();
Publicboolean IseRensated ();
Publicstaticboolean прервано ();
// Присоединяйтесь к методу
publicvoid join () бросает прерывание
После того, как поток установлен, он не выполняет код в методе запуска, но находится в состоянии ожидания. Когда поток находится в состоянии ожидания, вы можете использовать метод класса потока для установки различных свойств потока, таких как приоритет потока (SetPriority), имя потока (SetName) и тип потока (SetDaemon) и т. Д.
После вызова метода запуска, поток начинает выполнять код в методе выполнения. Поток входит в состояние бега. Вы можете использовать метод ISALIVE класса потока, чтобы определить, находится ли поток в состоянии работы. Когда поток находится в состоянии бега, Isalive возвращает True. Когда Isalive возвращает ложь, поток может находиться в состоянии ожидания или в состоянии остановки. Следующий код демонстрирует переключение между тремя состояниями создания, запуска и остановки потоков, и выводит соответствующее возвращаемое значение ISALIVE.
Как только поток начнет выполнять метод выполнения, поток не выходит из метода выполнения. Однако во время выполнения потока поток может быть временно остановлен двумя методами. Эти два метода приостановлены и спят. После приостановки потока с приостановкой поток можно разбудить с помощью метода резюме. После использования сна для сна, нить можно помещать в состояние готового состояния только после установленного времени (после того, как поток спит, поток может не выполняться немедленно, но он просто входит в состояние готового состояния и ожидает планирования системы).
При использовании метода сна есть две вещи:
1. Метод сна имеет две формы перегрузки. Одна из форм перегрузки может быть установлена не только на миллисекунд, но и наносекунд (1 000 000 наносекунд равны 1 миллисекунд). Тем не менее, виртуальные машины Java на большинстве платформ операционной системы не могут быть точными для наносекунд, поэтому, если наносекунд будут установлены для сна, виртуальная машина Java приведет к миллисекундам наиболее близко к этому значению.
2. При использовании метода сна вы должны использовать броски или попробовать {…} Catch {…}. Поскольку метод выполнения не может использовать броски, вы можете использовать только try {…} catch {…}. Когда поток спит, сон бросит исключение прерванного эктриэкмикции при прерывании потока, используя метод прерывания. Метод сна определяется следующим образом:
Publicstaticvoid Sleep (Long Millis) бросает прерывания
Publicstaticvoid Sleep (Long Millis, int nanos) бросает прерывания
Есть три способа прекратить поток.
1. Используйте флаг Exit, чтобы нормально выходить из потока, то есть поток заканчивается при завершении метода выполнения.
2. Используйте метод остановки для насильственного прекращения потока (этот метод не рекомендуется, потому что остановка совпадает с приостановкой и резюме, а также может иметь непредсказуемые результаты).
3. Используйте метод прерывания, чтобы прервать поток.
1. Используйте флаг Exit, чтобы завершить потоку
Когда метод запуска будет выполнен, поток выйдет. Но иногда метод запуска никогда не заканчивается. Например, использование потоков для прослушивания запросов клиентов в серверных программах или других задач, которые требуют обработки цикла. В этом случае эти задачи обычно помещаются в петлю, например, во время петли. Если вы хотите, чтобы цикл работал навсегда, вы можете использовать в то время как (true) {…}, чтобы справиться с ним. Однако, если вы хотите сделать выходной цикл в определенном состоянии, наиболее прямой способ состоит в том, чтобы установить флаг логического типа и контролировать, выходит ли while Loop, установив этот флаг на True или False. Вот пример завершения потока, используя флаг выхода.
Функция метода соединения состоит в том, чтобы превратить асинхронную поток выполнения в синхронное выполнение. То есть, когда будет вызван метод начала экземпляра потока, метод вернется немедленно. Если значение, рассчитанное этим потоком, должно использоваться после вызванного метода начала, необходимо использовать метод соединения. Если вы не используете метод соединения, нельзя гарантировать, что при выполнении оператора за началом будет выполнено поток. После использования метода соединения программа не будет выполнена до тех пор, пока поток не выходит. Следующий код демонстрирует использование присоединения.
3. Проблемы с многопоточной безопасностью
Причина проблемы: когда в одном и том же потоке работают несколько операторов для обмена данными, один поток выполняет только часть нескольких операторов, но еще не закончил выполнять их, а другой поток участвует в выполнении, что приводит к ошибке в данных обмена данными.
Решение: Для нескольких операторов, которые делятся данными с несколькими операциями, можно выполнить только один поток. В процессе выполнения другие потоки не выполняются.
Синхронизировать кодовые блоки:
public Class Threaddemo3 {public static void main (string [] args) {билет t = new Ticket (); Поток T1 = новый поток (T, «окно One»); Поток T2 = новый поток (T, «окно два»); Поток T3 = новый поток (t, «окно третьем»); Потока T4 = новый поток (T, «окно четыре»); t1.start (); t2.start (); t3.start (); t4.start (); }} класс билет реализует runnable {private int ticket = 400; public void run () {while (true) {synchronized (new object ()) {try {thread.sleep (1); } catch (прерванная экспрессия e) {// todo автоматически сгенерированный блок e.printstacktrace (); } if (билет <= 0) перерыв; System.out.println (think.currentThread (). GetName ()+"--- Продать"+Ticket--); }}}}Синхронные функции
public Class Threaddemo3 {public static void main (string [] args) {билет t = new Ticket (); Поток T1 = новый поток (T, «окно One»); Поток T2 = новый поток (T, «окно два»); Поток T3 = новый поток (t, «окно третьем»); Потока T4 = новый поток (T, «окно четыре»); t1.start (); t2.start (); t3.start (); t4.start (); }} класс билет реализует runnable {private int ticket = 4000; public Synchronized void saleticket () {if (ticket> 0) System.out.println (Thread.currentThread (). getName ()+"Проданный"+Ticket--); } public void run () {while (true) {saleticket (); }}}Блокировка синхронной функции является этой статической синхронизационной блокировкой
Связь между потоками
открытый класс ThreadDemo3 {public static void main (string [] args) {class person {public String name; частный строковый пол; public void set (string name, string gender) {this.name = name; this.gender = пол; } public void get () {System.out.println (this.name+"...."+this.gender); }} окончательный человек p = new Person (); Новый поток (new Runnable () {public void run () {int x = 0; while (true) {if (x == 0) {p.set ("zhang san", "male");} else {p.set ("lili", "nv");} x = (x+1)%2;}}}). новый поток (new Runnable () {public void run () {while (true) {p.get ();}}}). start (); }}/ *Zhang San .... мужчина Zhang San .... мужчина lili .... nvlili .... мужчина Zhang San .... nvlili .... мужчина */Измените приведенный выше код
открытый класс ThreadDemo3 {public static void main (string [] args) {class person {public String name; частный строковый пол; public void set (string name, string gender) {this.name = name; this.gender = пол; } public void get () {System.out.println (this.name+"...."+this.gender); }} окончательный человек p = new Person (); Новый поток (new Runnable () {public void run () {int x = 0; while (true) {synchronized (p) {if (x == 0) {p.set ("zhang san", "male");} else {p.set ("lili", "nv");} x = (x+1)%2;}}}).) новый поток (new Runnable () {public void run () {while (true) {synchronized (p) {p.get ();}}}}}). start (); }} /* lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili ... Сан .... мужчина Чжан Сан .... Мужчина */В ожидании механизма пробуждения
/**Механизм пробуждения в потоке*ждать и пробуждение должно быть тем же блокировкой*/public class threaddemo3 {private static boolean flags = false; public static void main (string [] args) {class person {public String name; частный строковый пол; public void set (string name, string gender) {this.name = name; this.gender = пол; } public void get () {System.out.println (this.name+"...."+this.gender); }} окончательный человек p = new Person (); New Thread (new Runnable () {public void run () {int x = 0; while (true) {synchronized (p) {if (flags) try {p.wait ();} catch (прерывание Exception e) {// todo автоматически сгенерированный блок e.printStacktrace ();}; если (x == 0) {p.set (p.set (); } else {p.set ("lili", "nv"); New Thread (new Runnable () {public void run () {while (true) {synchronized (p) {if (! flags) try {p.wait ();} catch (urrupteDexception e) {// todo Auto-генегенерированный блок E.printStacktrace ();}; p.get (););) flags = false; p.notifyall ();););););););););););););););););););););););););););););); }).начинать(); }}Механизм производства и потребления один
открытый класс ThreadDemo4 {Private Static Boolean Flags = false; public static void main (string [] args) {class goods {private String name; частный int num; public Synchronized void -продукт (String name) {if (flags) try {wait (); } catch (прерванная экспрессия e) {// todo автоматически сгенерированный блок e.printstacktrace (); } this.name = name+"номер:"+num ++; System.out.println ("произведен ......"+this.name); флаги = true; notifyAll (); } public Synchronized void потребление () {if (! flags) try {wait (); } catch (прерванная экспрессия e) {// todo автоматически сгенерированный блок e.printstacktrace (); } System.out.println ("потребляется *****"+name); флаги = false; notifyAll (); }} окончательный товар g = new Goods (); новый поток (new Runnable () {public void run () {while (true) {g.produce ("product");}}}). start (); новый поток (new Runnable () {public void run () {while (true) {g.consume ();}}}). start (); }}Механизм производства и потребления 2
открытый класс ThreadDemo4 {Private Static Boolean Flags = false; public static void main (string [] args) {class goods {private String name; частный int num; public Synchronized void -продукт (String name) {while (flags) try {wait (); } catch (прерванная экспрессия e) {// todo автоматически сгенерированный блок e.printstacktrace (); } this.name = name+"номер:"+num ++; System.out.println (think.currentThread (). GetName ()+"Производился ..."+this.name); флаги = true; notifyAll (); } public synchronized void unsume () {while (! Flags) try {wait (); } catch (прерванная экспрессия e) {// todo автоматически сгенерированный блок e.printstacktrace (); } System.out.println (thread.currentThread (). GetName ()+"потребляется *******"+name); флаги = false; notifyAll (); }} окончательный товар g = new Goods (); New Thread (new Runnable () {public void run () {while (true) {g.produce ("product");}}}, "продукт (" Продукт ");}}}," Производство ("Продукт");}}}, "продукт (" Продукт ");}}}," Продукт («Продукт»); }, "Потребитель № 1"). Start (); потребляется ******* Номер товара: 48050PRODUCER № 1 Производится ... Номер товара: 48051 Конвейн № 2 Потребляется **** Номер товара: 48051Producer № 2 48053 Ансомер № 1 был поглощен ******* Номер товара: 48053 Продавчик № 1 был произведен ... Компромиссный номер: 48054CONSUMER № 2 был потреблен ******* Номер товара: 48054Producer № 2. 48055*/Выше приведено сборник многопоточной информации Java. Мы будем продолжать добавлять соответствующие знания в будущем. Спасибо за поддержку этого сайта!