току. Кількість виконуваних інструкцій за кожен підхід не визначено.
Те, що інструкції паралельних потоків виконуються упереміш, в деяких випадках може призвести до конфліктів доступу до даних. Проблемам взаємодії потоків буде присвячена наступна стаття, а поки про те, як запускаються потоки в Java.
1.3 Запуск потоків
Кожен процес має хоча б один виконується потік. Той потік, з якого починається виконання програми, називається головним. У мові Java, після створення процесу, виконання головного потоку починається з методу main (). Потім, у міру необхідності, в заданих програмістом місцях, і при виконанні заданих ним же умов, запускаються інші, побічні потоки.
У мові Java потік представляється у вигляді об'єкта-нащадка класу Thread. Цей клас інкапсулює стандартні механізми роботи з потоком.
Запустити новий потік можна двома способами:
Спосіб 1
Створити об'єкт класу Thread, передавши йому в конструкторі щось, що реалізує інтерфейс Runnable. Цей інтерфейс містить метод run (), який буде виконуватися в новому потоці. Потік закінчить виконання, коли завершиться його метод run ().
Виглядає це так (Приклад 1.):
class SomeThing//Щось, що реалізує інтерфейс RunnableRunnable//(що містить метод run ())
{void run ()//Цей метод буде виконуватися в побічному потоці
{. out.println ( Привіт з побічного потоку! );
}
} class Program//Клас з методом main ()
{SomeThing mThing;//mThing - об'єкт класу, що реалізовує інтерфейс Runnablestatic void main (String [] args)
{= new SomeThing (); myThready=new Thread (mThing);//Створення потоку myThready .start ();//Запуск потока.out.println ( Головний потік завершений ... );
}
}
Для більшого укорочення коду можна передати в конструктор класу Thread об'єкт безіменного внутрішнього класу, що реалізовує інтерфейс Runnable:
Приклад 2.
public class Program//Клас з методом main ().
{static void main (String [] args)
{
//Створення потокаmyThready=new Thread (new Runnable ()
{void run ()//Цей метод буде виконуватися в побічному потоці
{. out.println ( Привіт з побічного потоку! );
}
}) ;. start ();//Запуск потока.out.println ( Головний потік завершений ... );
}
}
Спосіб 2 (Приклад3.)
Створити нащадка класу Thread і перевизначити його метод run (): AffableThread extends Thread
{
Overridevoid run ()//Цей метод буде виконаний в побічному потоці
{. out.println ( Привіт з побічного потоку! );
}
} class Program
{AffableThread mSecondThread; static void main (String [] args)
{= new AffableThread ();//Створення потока.start ();//Запуск потоку
System.out.println ( Головний потік завершений ... );
}
}
У наведеному вище прикладі в методі main () створюється і запускається ще один потік. Важливо відзначити, що після виклику методу mSecondThread.start () головний потік продовжує своє виконання, не чекаючи поки породжений ним потік завершиться. І ті інструкції, які йдуть після виклику методу start (), будуть виконані паралельно з інструкціями потоку mSecondThread.
Для демонстрації паралельної роботи потоків розглянемо програму, в якій два потоки сперечаються на предмет філософського питання «що було раніше, яйце чи курка?». Головний потік впевнений, що першою була курка, про що він і буде повідомляти кожну секунду. Другий же потік разів на секунду буде спростовувати свого опонента. Всього суперечка триватиме 5 секунд. Переможе той потік, який останнім прорече свою відповідь на це, без сумніву, животрепетне філософське питання. У прикладі використовуються кошти, (isAlive () sleep () і join ()). До них дані коментарі, а більш докладно вони будуть розібрані далі.
Приклад 4
class EggVoice extends Thread
{
Overridevoid run ()
{(int i=0; i lt; 5; i ++)
{
try {
sleep (1000);//Припиняє потік на 1 секунду
} catch (InterruptedException e) {}
.out.println ( яйце! );
}
//Слово «яйце» сказано 5 раз
}
}
class ChickenVoice//Клас з методом main ()
{EggVoice mAnotherOpinion;//Побічний потокstatic void main (String [] args)
{= new EggVoice ();//Створення потока.out.println ( Суперечка розпочато ... ) ;. start ();// Запуск потоку (int i=0; i lt; 5; i ++)
{{. sleep (1000);//Припиняє потік на 1 секунду
} catch (InterruptedException e) {}. out.println ( курка! );
}
//Слово «курка» сказано 5 раз (mAnotherOpinion.isAlive ())//Якщо опонент ще не сказав останнє слово
{{. join ();//Почекати поки опонент закінчить висловлювати...