Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

// некоторое долгое действие, вычисление




// некоторое долгое действие, вычисление

long sum=0;

for (int i=0; i< 1000; i++)

sum+=i;

System. out. printin(sum);

}

}

Также незначительно меняется процедура запуска потока:

Runnable r= new MyRunnable();

Thread t = new Thread(r);

// либо так: Thread t = new Thread(new MyRunnable());

t. start ();

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

Thread(Runnable объект_потока, String имя_потока)

В первом параметре указывается экземпляр класса, реализующего интерфейс. Он определяет, где начнётся выполнение потока. Во втором параметре передаётся имя потока.

Если раньше объект, представляющий сам поток выполнения, и объект с методом rип(), содержащим полезную функциональность, были объединены в одном экземпляре класса MyThread, то теперь они разделены. Какой из двух подходов удобней, решается в каждом конкретном случае. Подчеркнем, что Runnable не является полной заменой классу Thread, поскольку создание и запуск самого потока исполнения возможно только через метод Thread. startQ.

Интерфейс Runnable не имеет метода start(), а только единственный метод run(). Поэтому для запуска такого потока, как t следует создать экземпляр класса Thread с передачей экземпляра r его конструктору. Однако при прямом вызове метода run() поток не запустится, выполнится только тело самого метода.

 

Для того, чтобы уже закончить с классом Thread , коснемся еще нескольких его возможностей.

1. У потоков могут быть различные приоритеты. Существует несколько констант - Thread. MIN_PRIORITY == 1, Thread. NORM_PRIORITY == 5 И Thread. MAX_PRIORITY == 10.

2. Значения эти внутренние и с реальными приоритетами потоков в операционной системе соотносятся слабо.

3. Потоки могу быть т. н. демонами. Такой поток отличается от обычного тем, что он не препятствует окончанию работы виртуалыой машины. Т. е. можно сказать, что виртуальная машина работает, пока существует хотя бы один поток, не являющийся демоном. Потоки- демоны удобно использовать для фоновых задач.

4. Поток можно приостановить на определенный промежуток времени. Изнутри. Делается это через статический метод Thread , sleep () c параметром - количеством миллисекунд, на которое приостанавливается поток. До истечения этого времени поток может быть выведен из состояния ожидания вызовом interrupt, о котором будет сказано ниже.

5. И последнее, чего бы хотелось коснуться - статический метод yield . Он служит для передачи управления другим потокам. Т. е. в результате его вызова происходит переключение контекста и процессор начинает исполнять код другого потока. Это нужно как в ситуациях, когда работа на текущий момент завершена и можно дать поработать другим (например, поток обрабатывает данные, все обработал, а новые еще не пришли), так и в ситуациях, когда поток занимается какими-нибудь интенсивными действиями, съедает большую часть процессора и не дает другим потокам работать (встречается в основном под Java ME, в условиях ограниченных ресурсов). Обратите внимание, что этот метод статический и действует только на текущий поток. Заставить таким образом чужой поток поделиться своим временем нельзя!

5. 2. Примеры, демонстрирующие необходимость потоков

Для того, чтобы убедиться в необходимости потоков, давайте рассмотрим пример " Безответного пользовательского интерфейса":

При нажатии на кнопку " Start Counting" начнется отсчет, результат должен появиться в поле " Counter". Нажатие кнопки " Stop Counting" должно остановить (приостановить) подсчет. Дваобработчика событий нажатия кнопок общаются через boolean флаг под названием stop. Обработчик стоп- кнопки устанавливает stop флаг; в то время как обработчик кнопки пуск проверяет, был ли stop флаг установлен, прежде чем продолжить счет.

Пример 5. 2. 1.

Проект назовем UnresponsiveUI

import java. awt. *; import java. awt. event. *; import javax. swing. *; /** Illustrate Unresponsive UI problem caused by " busy" Event-Dispatching Thread */public class UnresponsiveUI extends JFrame { private boolean stop = false; // start or stop the counter private JTextField tfCount; private int count = 1;    /** Constructor to setup the GUI components */ public UnresponsiveUI() {      Container cp = this. getContentPane(); cp. setLayout(new FlowLayout(FlowLayout. CENTER, 10, 10)); cp. add(new JLabel(" Counter" )); tfCount = new JTextField(count + " ", 10); tfCount. setEditable(false); cp. add(tfCount);       JButton btnStart = new JButton(" Start Counting" ); cp. add(btnStart); btnStart. addActionListener(new ActionListener() {    @Override    public void actionPerformed(ActionEvent evt) {       stop = false;        for (int i = 0; i < 100000; ++i) {          if (stop) break; // check if STOP button has been pushed,                             // which changes the stop flag to true          tfCount. setText(count + " " );           ++count;        }     } }); JButton btnStop = new JButton(" Stop Counting" ); cp. add(btnStop); btnStop. addActionListener(new ActionListener() {    @Override    public void actionPerformed(ActionEvent evt) {       stop = true; // set the stop flag    } });       setDefaultCloseOperation(JFrame. EXIT_ON_CLOSE); setTitle(" Counter" ); setSize(300, 120); setVisible(true); }    /** The entry main method */ public static void main(String[] args) { // Run GUI codes in Event-Dispatching thread for thread safety SwingUtilities. invokeLater(new Runnable() {    public void run() {       new UnresponsiveUI(); // Let the constructor do the job    } }); }

}

Однако, при нажатии кнопки " Start Counting" пользовательский интерфейс замораживается - значение счетчика не обновляется на дисплеї, а пользовательский интерфейс не реагирует на нажатия кнопки " Stop Counting", или любое др> roe взаимодействие с пользователем.

 

Последовательность работы программы UnresponsiveUI следющая:

1. Метод main () стартует и потоке " main"

2. Подсистема ОКОН окружения JRE, через Swingutilities. invokeLater() запускает 3 потока: " A WT-Windows" (daemon thread), " AWT-Shutdown" и " AWT-EventQueue-O". Последний известен как поток диспегчиризации (Event-Dispatching Thread -EDT), это единственный поток, отвественный за управлением всех событий (таких, например как нажатие кнопки) и обновления экрана для обеспечения безопасности потока в GUI и манипуляции GUI компонентами. Конструктор UnresponsiveUi () согласно планировщику запускается в потоке Event-Dispatching (методом invokeLater о), после этого обрабатываются все события. Поток " main" " живет" и после того, как метод main о завершается. Запукается новый поток с именем " DestroyJavaVM".

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...