Главная » Java » Основы многопоточности

1

До   этого   все   действия   в   наших   программах   выполнялись последовательно  –  одно  за  другим.  Если  программа  вызывает  два метода,  второй  метод  ждет,  пока  не  выполнится  первый.  Другими словами,  каждая   из  наших   программ   имеет   только   один   поток исполнения  (a thread).

Однако, в реальной жизни мы  можем делать несколько вещей одновременно,  например, есть, разговаривать по телефону, смотреть телевизор   и делать домашнее задание. Чтобы выполнять все эти

действия параллельно, мы  используем несколько процессоров:   руки, глаза  и рот.

На  сегодня,  вo  многих  компьютерах  тоже  два  или  более  процессоров (CPU). Хотя, возможно, в вашем компьютере только один процессор, который считает,  посылает  команды  монитору,  диску,  удаленным компьютерам и т.д.

Но  даже один процессор может выполнять несколько действий сразу, если программа использует несколько потоков (multiple threads). Один Java-­?класс может запустить несколько потоков исполнения, которые будут меняться и получать свою долю процессорного времени.Хороший пример программы, которая создает несколько потоков – это web-­?браузер.   Вы  можете смотреть Интернет-­?сайты,   пока качаются несколько файлов – одна программа запускает два потока исполнения.

В  следующей  версии  нашей  пинг-­?понг игры будет  один  поток для отрисовки  стола.  Второй  поток  будет  считать  координаты  мяча  и ракеток,  и  посылать  команды  по  отрисовке  окна  первому  потоку.  Но сначала,  я покажу вам две очень простые программы, чтобы  вы  лучше поняли, зачем нужны потоки.Каждая   из  этих   программ   будет отображать  кнопку и текстовое поле.

Когда  вы нажмете  кнопку  Kill   Time, программа   начнет   цикл, который  увеличивает значение переменной триста  тысяч раз. Текущее значениеэтой  переменной  будет  отображаться  в  заголовке  окна.  В  классе NoThreadsSample  только  один  поток  исполнения  и  вы  не  сможете ничего  напечатать  в  текстовом  поле,  пока  цикл  не  закончится. Этот цикл забирает все процессорное время, поэтому окно заблокировано.

Скомпилируйте  и запустите этот класс, чтобы убедиться, что окно блокируется в течение некоторого времени. Заметьте, что этот класс создает экземпляр класса JTextField и передает  его в панель контента без создания переменной. Если вы не планируете получать или устанавливать атрибуты этого объекта, вам не нужна такая переменная.

import javax.swing.*; import java.awt.GridLayout;

import java.awt.event.ActionListener;

import java.awt.event.ActionEvent;

public class NoThreadsSample extends JFrame

implements ActionListener{

// Конструктор

NoThreadsSample(){

// Создать окно с кнопкой и текстовым полем

GridLayout gl =new GridLayout(2,1);

this.getContentPane().setLayout(gl);

JButton myButton = new JButton("Kill Time");

myButton.addActionListener(this);

this.getContentPane().add(myButton);

this.getContentPane().add(new JTextField());

}

// Обработчик нажатия кнопки

public void actionPerformed(ActionEvent e){

// Просто заморозить на некоторое время,

// чтобы показать, что окно заблокировано

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

this.setTitle("i="+i);

}

}

public static void main(String[] args) {

// Создать окно   NoThreadsSample myWindow = new NoThreadsSample();

// Убедиться, что окно закрывается при нажатии на крестик в углу myWindow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);// Установить размеры окна – координаты левого верхнего

//угла и высоту с шириной

myWindow.setBounds(0,0,150, 100);

//Сделать окно видимым    myWindow.setVisible(true);

}

}

Следующая  версия этого маленького окошка будет создавать и запускать отдельный поток для цикла, и главный поток окна позволит печатать в текстовом поле, пока цикл выполняется.Вы можете создать поток одним из следующих способов:??  Создать  экземпляр  Java-­?класса  Thread  и  передать  ему объект,  который  реализует  интерфейс  Runnable.  Если  ваш  класс  реализует интерфейс Runnable, код будет выглядеть так:

Thread worker = new Thread(this);

     Этот  интерфейс требует написать в методе run() код, который      будет выполняться в отдельном потоке.

worker.start();

??  Создать  подкласс  класса  Thread  и  реализовать  метод  run(). Длятого,  чтобы запустить поток, надо вызвать метод start().public class MyThread extends Thread{

public static void main(String[] args) { MyThread worker = new MyThread();

worker.start();

}

public void run(){

// Здесь будет ваш код

}

}

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

import javax.swing.*; import java.awt.GridLayout;

import java.awt.event.ActionListener;

import java.awt.event.ActionEvent;

public class ThreadsSample extends JFrame

implements ActionListener, Runnable{

// Конструктор   ThreadsSample(){

// Создать окно с кнопкой и текстовым полем     GridLayout gl =new GridLayout(2,1);

this.getContentPane().setLayout(gl);

JButton myButton = new JButton("Kill Time"); myButton.addActionListener(this); this.getContentPane().add(myButton);

this.getContentPane().add(new JTextField());

}

public void actionPerformed(ActionEvent e){

// Создать поток и выполнить “замораживающий” код

// без блокировки

Thread worker =  new Thread(this);

worker.start();  // вызывает метод run()

}

public void  run(){

// Заморозить на некоторое время, чтобы показать, что   // элементы окна НЕ блокируются

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

this.setTitle("i="+i);

}

}

public static void main(String[] args) { ThreadsSample myWindow = new ThreadsSample();

//Убедись,что окно закрывается по нажатию на крестик в углу     myWindow.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE);

// Установи размеры окна и сделай его видимым

myWindow.setBounds(0,0,150, 100);

myWindow.setVisible(true);

}

}

После нажатия на кнопку Kill  Time, класс ThreadsSample запускает новый  поток. После этого, поток  с циклом и главный поток  получают по  своей доле процессорного времени. И теперь вы  можете печатать в текстовом поле (главный поток), пока другой поток выполняет цикл!Изучение  потоков заслуживают гораздо большего внимания, чем эти несколько страниц, и я рекомендую вам почитать дополнительный материалы по этой теме.

Источник: Java  Programming for Kids, Parents and Grandparents by Yakov Fain

По теме:

  • Комментарии

1 комментарий

  1. Артем says:

    Ребята – отличный ресурс! – Так держать! Но ради Бога – сделайте нормальную подсветку синтаксиса и форматирование кода.