Программирование - это просто
Advertisement
Главная arrow Уроки программирования arrow Java для чайников. arrow Java для чайников. Урок 5. Потоки (awt, thread).
26.04.2024 г.
Главное меню
Главная
Интернет магазин
Программные продукты
Биржевые роботы
Искусственный интеллект
Математика и информатика
1С:Предприятие
Уроки C#
Уроки Delphi
Уроки программирования
Web-программирование
Дизайн и графика
Компьютер для блондинок
Исходники
Статьи
Платный раздел
Рассказы про компьютеры
Хитрости и секреты
Системный подход
Размышления
Наука для чайников
Друзья сайта
Excel-это не сложно
Все о финансах
.
Java для чайников. Урок 5. Потоки (awt, thread). Печать E-mail
Автор megabax   
15.09.2011 г.
В этой статье я постараюсь максимально просто и понятно изложить основы программирования на языке Delphi

Java для чайников. Урок 5. Потоки (awt, thread).

Посмотреть пример апплета, разработанного на данном уроке, можно здесь.

 

Сегодня мы изучим понятие потока. Дело в том, что под операционной системой Windows может одновременно выполнятся несколько задач. На самом дел, конечно, одновременность кажущаяся. Каждая задача выполнятся кусочками по очереди, но так как это происходит очень быстро, то кажется, что программы выполняются одновременно. Java так же поддерживает многозадачность. Для этого в ней существует такой класс, как Theard - поток. В программе можно запустить несколько потоков, выполняющихся одновременно. Например, пока пользователь что то набирает, можно в фоновом режиме запустить какой нибудь длительный процесс расчета или загрузки данных.

Для демонстрации работы с потоками рассмотрим пример программы "гонки". В качестве гоночной дорожки у нас будут черны линии, а в качестве гонщиков - желтые овалы:

Java для чайников. Урок 5. Потоки (awt, thread).

 

Каждый гонщик - это отдельный поток. Гонщика реализует класс Racer, объявленный  от интерфейса Runnable:

 

import java.awt.Graphics;

import java.awt.Color;

 

//класс поточный, поэтому он должен наследовать интерфейс Runnable

public class Racer extends java.awt.Canvas implements Runnable {

    int position=0;

    String name;

    int stepsCount=600;

    boolean isFinished;  //флаг, что гонщик пришел на финиш

   

    //конструктор класса

    //экземпляр класса создаем по имени

    public Racer (String aName) {

        name=aName;

    }

   

    public synchronized void paint(Graphics g) {

   

        //рисуем дорожку

        g.setColor(Color.black);

        g.drawLine(0,size().height/2,size().width-170,size().height/2);

       

        //рисуем гонщика в виде желтого овала

        if(isFinished) g.setColor(Color.green); else g.setColor(Color.yellow);

        g.fillOval(position*(size().width-170)/stepsCount,0,15,size().height);

       

        //если гонщик пришел на финиш, выдадим об этом сообщение

        if(isFinished) {

            g.setColor(Color.red);

            g.drawString("Racer '"+name+"' is finished",size().width-150,size().height);

        }

       

        g.setColor(Color.red);

        g.drawString(""+position,0,size().height);

    }

   

    public void run() {

        isFinished=false;

       

        //цикл до конца гонки

        while(position<stepsCount) {

            position++;

            repaint();

           

            //останавливаем поток, что бы началось отображение

            try {

                Thread.currentThread().sleep(10);

            } catch (Exception e) {System.out.println("Exception on sleep");}

        }

        isFinished=true;

        repaint();

    }

}

 

Класс, который будет выполнятся в потоке, должен иметь метод run, которым его запускают в режим поточного выполнения. Разные потоки могут обращаться к одним и тем же данным. Дабы избежать конфликта, в Java используется синхронизация. Синхронизировать можно метод, объявив его с модификатором synchronized, либо целый блок, так же используя ключевое слово synchronized. Сегодня мы подробно на синхронизации останавливается не будем,  так как цель настоящего урока дать общие представления о потоках. Но к многопоточным приложениям мы еще вернемся и разберем их более подробно. А сейчас рассмотрим некоторые методы класса Thread:

  • start(). Запускает поток на выполнение.

  • stop(). Заканчивает выполнение потока.

  • sleep(long msec). Останавливает выполнение потока на указанное количество миллисекунд.

  • yield(). Передает ресурсов процессора другому потоку.

  • suspend(). Приостанавливает выполнение потока.

  • resume(). Возобновляет выполнение потока.

В нашем примере мы используем метод sleep, что бы приостановить на время выполнение потока, дав возможность перерисовать картинку на экране. Если этого не делать, программа просто повиснет.

И так, с классом "гонщика" понятно, тем более в тексте программы есть комментарии. Поэтому переходим к основному классу програмы:

import java.awt.Graphics;

import java.awt.GridLayout;

 

 

public class Race extends java.applet.Applet implements Runnable {

    Racer theRacers[]; //массив гонщиков

    static int count=3; //количество гонщиков

    Thread theThreads[]; //массив потоков

    Thread thisThread; //основной поток (поток, который управляет другими потоками)

    static boolean inApplet=true;

    int numberOfTheradAtStart; //в конце программы при помощи этой переменной

                               //определяем, все ли потоки прекратили существование

   

    public void init() {

        numberOfTheradAtStart=Thread.activeCount();

       

        //определеяем расположение гонщиков в окне,

        //они будут добавлятся один за друим

        setLayout(new GridLayout(count,1));

       

        //создаем массивы гонщиков и потоков

        theRacers=new Racer[count];

        theThreads=new Thread[count];

       

        //в цикле создаем каждый элемент массивов

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

            theRacers[i]=new Racer("Racer "+i);

            theRacers[i].resize(size().width,size().height/count);

            add(theRacers[i]);

            theThreads[i]=new Thread(theRacers[i]);

        }

    }

   

    //этой процедурой мы запускаем все потоки

    public void start() {

        for(int i=0;i<count;i++) theThreads[i].start();

        thisThread=new Thread(this);

    }

   

    public void stop() {

        thisThread.stop();

    }

   

    public void run() {

   

        // цикл, пока все гонщики не закончат гонку

        while(Thread.activeCount()>numberOfTheradAtStart+2) {

            try {

                thisThread.sleep(100);

            } catch (InterruptedException e) {

                System.out.println("thisTread was interruped");

            }

        }

       

        if(inApplet) {

            stop();

            destroy();

        } else System.exit(0);

    }

   

    public static void main(String argv[]) {

        inApplet=false;

        Race theRace=new Race();

        theRace.init();

        theRace.start();

    }

}

 

Работает эта программа следующим образом:

1. Создает экземпляр самой себя.

2. Вызывает у этого экземпляра процедуру инициализации, в которой создает массив гонщиков и массив потоков. В цикле заполняет эти массивы.

3. Вызывает процедуру start(), в которой запускает потоки для гонщиков, затем создает и запускает поток для самой себя.

 

Далее все работает в потоках. У всех объектов периодически вызывается метод run. В том числе и у главного класса. В этом случае проихсодит проверка, все ли потоки завершены, если нет - поток так же на некоторое время останавливает себя, дав другим потокам поработать. Если все гонщики пришли на финиш:

Java для чайников. Урок 5. Потоки (awt, thread).

то главный поток завершает самого себя.

 

(С) Шуравин Александр

 

 

Последнее обновление ( 15.09.2011 г. )
 
« След.   Пред. »
 
© 2024 Программирование - это просто
Joomla! - свободное программное обеспечение, распространяемое по лицензии GNU/GPL.
Русская локализация © 2005-2008 Joom.Ru - Русский Дом Joomla!
Design by Mamboteam.com | Powered by Mambobanner.de
Я принимаю Яндекс.Деньги