В этой статье в основном изучаются примеры кода традиционной технологии синхронизации потоков, связанной с параллелизмом Java, следующим образом.
Сначала посмотрим на вопрос:
Есть две темы. Сначала работа дочернего поток выполняется 10 раз, затем основной поток выполняется 5 раз, а затем переключается на детскую потоку, выполняющую 10, а затем основной поток выполняется 5 раз ... эта обработка в рамках обработки в 50 раз.
После прочтения этого вопроса очевидно, что общение между потоками используется. Позвольте мне сначала проанализировать идею: сначала должно быть два потока, а затем в каждом потоке должно быть 50 петель, потому что каждый поток должен выполнять задачи в 50 раз в оба конца, основная задача-выполнить 5 раз, а задача дочернего потока состоит в том, чтобы выполнить 10 раз. Межпоточная коммуникационная технология в основном использует метод wait() и метод notify() . Метод wait () приводит к тому, что текущий поток ожидает и отпускает замок. Метод notify() указывает, что один поток, ожидающий этого монитора объекта, пробуждается. Давайте выполним эту проблему с межпоточной коммуникацией шаг за шагом.
Во -первых, независимо от связи между основным потоком и детским потоком, напишите задачи, которые должны выполняться каждым потоком:
Public Class TranterailThreadCommunication {public static void main (string [] args) {// Открыть детскую нить новую поток (new Runnable () {@Override public void run () {for (int i = 1; i <= 50; i ++) {synchronized (trateriaThreadCommunication.class) {// Субэт -потоковое значение: execute 10 раз (int j = 1; {System.out.println ("Последовательность подразделения" +j +", цикл" +i);}}}}}). Start (); // Основной метод является основным поток для (int i = 1; i <= 50; i ++) {synchronized (ntavelyThreadCommunication.class) {// Основное целое поток: execute 5 times (int j = 1; {System.out.println ("Последовательность основной потоки" + j + ", loop" + i);}}}}}}}}}}}}}}}}}}}Как упомянуто выше, каждый по двум потокам имеет 50 больших петель и выполняет 50 задач, задача дочернего потока выполняется 10 раз, а задача основного потока выполняется 5 раз. Чтобы обеспечить синхронизацию между двумя потоками, используются код синхронизации синхронизации, и используется та же самая блокировка: объект байткода класса. Это обеспечивает безопасность потока. Но этот дизайн не очень хорош. Так же, как я написал в тупике в предыдущем разделе, мы можем поместить задачи потоков в класс. Паттерн этой конструкции более структурирован, и размещение различных задач потока в один и тот же класс будет легко решить проблему синхронизации, поскольку его легко использовать в одном блоке в классе. Так что измените вышеуказанную программу:
public class tranterailThreadCommunication {public static void main (String [] args) {Business Business = new Business (); // Новый класс обработки задачи потока // Открыть детскую нить новую поток (new Runnable () {@Override public void run () {for (int i = 1; i <= 50; i ++) {bussiness.sub (i); Основной поток для (int i = 1; i <= 50; i ++) {bussiness.main (i);}}} // Общие данные (включая блокировки синхронизации) или несколько общих методов, которые будут использоваться, должны быть классифицированы в тот же класс. Этот дизайн просто отражает надежность программы кластеризации высокого класса. класс бизнес {public synchronized void sub (int i) {for (int j = 1; j <= 10; j ++) {System.out.println («Последовательность подзых" +j +", петля" +i);}} public synchronized void main (int i) {for (int j = 1; j <= 5; j ++) {System. J + ", петля" + i);}} После этой модификации структура программы становится более ясной и надежной. Просто добавьте синхронизированное ключевое слово в два метода задачи потока и используйте эту блокировку. Но между этими двумя потоками нет связи. Результатом выполнения является то, что основной потоковой сигнал вычеркивает задачу в 50 раз, а детская нить зацикливает задачу в 50 раз. Причина очень проста, потому что существует синхронизированная синхронизация.
Следующее продолжает улучшать программу, чтобы разрешить связь между двумя потоками, как описано в вопросе:
public class tranterailThreadCommunication {public static void main (String [] args) {Business Business = new Business (); // Новый класс обработки задачи потока // Открыть детскую нить новую поток (new Runnable () {@Override public void run () {for (int i = 1; i <= 50; i ++) {bussiness.sub (i); Основной поток для (int i = 1; i <= 50; i ++) {bussiness.main (i);}}} // Использование общих данных (включая блокировки синхронизации) или несколько общих методов должны быть классифицированы в один и тот же класс. Этот дизайн просто отражает надежность драмы Gao Lei и программы. класс бизнес {private boolean bshouldsub = true; public synchronized void sub (int i) {while (! bshouldsub) {// Если это не ваш очередь выполнять, попробуйте {this.wait (); // объект, который вызывает метод wait (), должен быть таким же, как и синхронизированный объект блокировки. Здесь синхронизирован находится на методе, поэтому используйте этот} catch (прерывание Exception e) {// todo, сгенерированный Auto-Catch Blocke.printstacktrace ();}} для (int j = 1; j <= 10; j ++) {System.out.println («Последовательность подменного потока» + j + », Loop of ' + i); this.notify (); // Разбудить ожидание основного потока} public Synchronized void main (int i) {while (bshouldsub) {// Если это не ваша очередь выполнить, try {this.wait ();} catch (urruptedException e) {// todo Auto Generated Catch.printStacktrace (); {// todo AutoGenceed Catch.printStackTrace ();); ++) {System.out.println ("Последовательность основной потоки" + J + ", цикл" + i);} bshouldsub = true; // Измените TAG this.notify (); // Пробуждение дочернего потока}}}}}}}}}}}}}Прежде всего, давайте не будем говорить о конкретной реализации программы, с структурной точки зрения, мы уже осознали преимущества этого дизайна: нет необходимости изменять что-либо в основной функции, и логика в отношении межпоточной синхронизации и межпоточного общения-это все в бизнес-классе. Различные потоки в основной функции должны только вызовать соответствующие задачи, размещенные в классе. Это отражает преимущества высокого хлопки.
Давайте снова посмотрим на конкретный код. Во -первых, определите логическую переменную, чтобы определить, какой поток следует выполнить. Когда это не детская нить, она будет спать. Тогда он естественным образом выполнит основной поток. После выполнения он изменит BshouldSub и разбудит детскую ветку. В настоящее время детская нить будет судить, что, хотя он не удовлетворен и не будет спать. Это выполнит задачу детского потока. Точно так же, после того, как основной поток только что изменил BSHOULDSUB, когда второй цикл используется для выполнения задачи основного потока, он будет спать и ждать, пока детский поток проснется. Это делает логику очень ясной. Основной поток и детская нить по очереди выполняют свои соответствующие задачи, и этот ритм в 50 раз в 50 раз.
Есть еще одно небольшое объяснение: на самом деле его можно использовать, если судить, но зачем использовать во время? Потому что иногда нить просыпается, это похоже на лунатинг, который, очевидно, спит, но встает). Если он использует, если, то после того, как он будет просыпаться, он не вернется к судье, если, а затем, естественно, выполнит задачу. Ладно, другой поток выполняется, и это повлияет на другую ветку в мгновение ока. Но если это какое -то время, это будет иначе. Даже если нить не бодрствует, она все равно будет судить, пока. Тем не менее, другой поток выполняется в это время. BSHOULDSUB не был изменен, поэтому он все еще входит во время и снова спит ~ так что он очень безопасен и не повлияет на другую ветку! Это также сделано в официальном документе JDK.
Давайте суммируем связь между потоками.
Выше приведено все подробное объяснение традиционного кода коммуникационной технологии общения с помощью Java Code, и я надеюсь, что это будет полезно для всех. Заинтересованные друзья могут продолжать ссылаться на другие связанные темы на этом сайте. Если есть какие -либо недостатки, пожалуйста, оставьте сообщение, чтобы указать это. Спасибо, друзья, за вашу поддержку на этом сайте!