Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lab12_Java_Vkazivky_2010_Multithreading.doc
Скачиваний:
7
Добавлен:
17.04.2019
Размер:
921.6 Кб
Скачать

17.2. Клас Thread

В класі Thread сім конструкторів:

  • Thread(ThreadGroup group, Runnable target, String name) — створює підпроцес з іменем name, належний групі group і виконуючий метод run() обєкта target. Це основной конструктор, всі інші звертаються до нього з тим чи іншим параметром, рівним null;

  • Thread() — створюваний підпроцесс буде виконувати свій метод run();

  • Thread(Runnable target);

  • Thread(Runnable target, String name);

  • Thread(String name);

  • Thread(ThreadGroup group, Runnable target);

  • Thread(ThreadGroup group, String name).

Імя підпроцесу name не має ніякого значення, воно не використовується віртуальною машиною Java і застосовується тільки для відрізняння підпроцесів в програмі. Після створення підпроцесу його треба запустити методом start(). Віртуальна машина Java почне виконувати метод run() цього обєкта-підпроцеса. Підпроцес завершить роботу після виконання метода run(). Для знищення обєкта-підпроцеса вслід за цим він повинен присвоїти значення null.

Виконуваний підпроцес можна призупинити статичним методом sleep (long ms) на ms мілісекунд. Цей метод ми уже використовували в попередніх уроках. Якщо обчислювальна система може відраховувати наносекунди, то можна призупинити підпроцес з точністю до наносекунд методом sleep(long ms, int nanosec). В лістинзі 17.1 приведено найпростіший приклад. Головний підпроцесс створює два підпроцеси з іменами Thread1 і Thread 2, виконуючих один і той же метод run(). Цей метод просто виводить 20 раз текст на екран, а потім повідомляє про своє завершення.

Лістинг 17.1. Два підпроцеси, запущені із головного підпроцесу

class OutThread extends Thread{

private String msg;

OutThread(String s, String name){

super(name); msg = s;

}

public void run()

{

for(int i = 0; i < 20; i++){

// try{

// Thread.sleep(100);

// }catch(InterruptedException ie){}

System.out.print(msg + " ");

}

System.out.println("End of " + getName());

}

} class TwoThreads{

public static void main(String[] args){

new OutThread("HIP", "Thread 1").start();

new OutThread("hop", "Thread 2").start();

System.out.println();

}

}

На рис. 17.1 показано результат двох запусків програми лістингу 17.1. Як бачите, в першому випадку підпроцес Thread1 встиг відпрацювати повністю до переключення процесора на виконання другого підпроцесу. В другому випадку робота підпроцеса Thread1 була перервана, процесор переключився на виконання підпроцеса Thread 2, встиг виконати його повністю, а потім переключився знову на виконання підпроцеса Thread1 і завершив його.

Рис. 17.1. Два підпроцеси працюють без затримки

Це дуже повчальний приклад, але якщо у вас сучасний компютер з більшою швидкістю дії, то запустивши на ньому програму лістингу 17.1 ви можете побачити зовсім іншу картину. Підпроцеси можуть спрацювати так швидко, що переключення не здійсниться.

Приберемо в лістинзі 17.1 коментарі, затримавши тим самим виконання кожної ітерації циклу на 0,1 секунди. Пуста обробка виключення InterruptedException означає, що ми ігноруємо спробу переривання роботи підпроцеса. На рис. 17.2 показано результат двох запусків програми. Як бачите, процесор переключається з одного підпроцеса на інший, але в одному місці регулярність переключення порушується і раніше запущений підпроцес завершується пізніше.

Як же досягти узгодженості, як говорять, синхронізації (synchronization) підпроцесів? Обговоримо це нижче, а поки що покажемо ще два варіанти створення тієї ж самої програми. В лістинзі 17.2 приведено другий варіант тієї ж програми: сам клас TwoThreads2 являється розширенням класу Thread, а метод run() реалізується прямо в ньому.

Лістинг 17.2. Клас розширює Thread

class TwoThreads2 extends Thread{

private String msg;

TwoThreads2(String s, String name){

super(name); msg = s;

}

public void run(){

for(int i = 0; i < 20; i++){

try{

Thread.sleep(100);

}catch(InterruptedException ie){}

System.out.print(msg + " ");

}

System.out.println("End of " + getName());

}

public static void main(String[] args)(

new TwoThreads2("HIP", "Thread 1").start();

new TwoThreads2("hop", "Thread 2").start();

System.out.println();

}

}

Третій варіант: клас TwoThreads3 реалізує інтерфейс RunnabІe. Цей варіант записаний в лістинзі 17.3. Тут не можна використовувати методи класу Thread, але зате клас TwoThreads3 може бутиь розширенням іншого класу. Наприклад, можна зробити його аплетом, розширивши клас Applet або JAppІet.

Лістинг 17.3. Реалізація інтерфейса Runnabie

class TwoThreadsS implements RunnabІe{

private String msg;

TwoThreads3(String s){ msg = s; }

public void run(){

forfint i = 0; i < 20; i++){

try{

Thread.sleep(100);

}catch(InterruptedException ie){}

System.out.print(msg + " ");

}

System.out.println("End of thread.");

}

public static void main (String[] args){

new Thread(new TwoThreads3("HIP"), "Thread 1").start ();

new Thread(new TwoThreads3("hop"), "Thread 2").start ();

System.out.println();

}

}

Рис. 17.2. Підпроцеси працюють із затримкою

Частіше всього в новому підпроцесі задаються нескінчені дії, виконувані на фоні основних дій: програється музика, на екрані крутиться анімований логотип фірми, біжить рекламний рядок. Для реалізації такого підпроцеса в методі run() задається нескінчений цикл, зупинюваний після того, як обєкт-підпроцес отримає значення null. В лістинзі 17.4 показано четвертий варіант тієї ж самої програми, в якій метод run() виконується до тих пір, доки поточний обєкт-підпроцес th співпадає з обєктом gо, запустившим поточний підпроцес. Для переривання його виконання передбачений метод stop(), до якого звертається головний підпроцес. Ця стандартна конструкція, рекомендована документацією J2SDK. Головний підпроцес в даному прикладі тільки створює обєкти-підпроцеси, чекає одну секунду і зупиняє їх.

Лістинг 17.4. Зупинка роботи підпроцесів

class TwoThreadsS implements Runnabie{

private String msg;

private Thread go;

TwoThreadsS(String s){

msg = s;

go = new Thread(this);

go.start();

}

public void run(){

Thread th = Thread.currentThread();

while(go == th){

try{

Thread.sleep(100);

}catch(InterruptedException ie){}

System.out.print(msg + " ");

}

System.out.println("End of thread.");

}

public void stop(){ go = null; }

public static void main(String[] args){

TwoThreadsS thl = new TwoThreadsS("HIP");

TwoThreadsS th2 = new TwoThreadsS("hop");

try{

Thread.sleep(1000);

}catch(InterruptedException ie){}

thl.stop(); th2.stop();

System.out.printlnf);

}

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]