Философия Java

         

Чтение и установка приоритетов


Можно определить приоритет процесса с помощью getPriority( ) и изменить его 

setPriority( ). Форму предыдущих примеров счетчиков "counter" можно использовать для демонстрации эффекта изменния приоритетов. В данном апплете можно видеть как счетчик замедляется по мере того, как его процесс получает низший приоритет:

//: c14:Counter5.java

// Adjusting the priorities of threads.

// <applet code=Counter5 width=450 height=600>

// </applet>

import javax.swing.*; import java.awt.*; import java.awt.event.*; import com.bruceeckel.swing.*;

class Ticker2 extends Thread { private JButton b = new JButton("Toggle"), incPriority = new JButton("up"), decPriority = new JButton("down"); private JTextField t = new JTextField(10), pr = new JTextField(3); // Display priority

private int count = 0; private boolean runFlag = true; public Ticker2(Container c) { b.addActionListener(new ToggleL()); incPriority.addActionListener(new UpL()); decPriority.addActionListener(new DownL()); JPanel p = new JPanel(); p.add(t); p.add(pr); p.add(b); p.add(incPriority); p.add(decPriority); c.add(p); } class ToggleL implements ActionListener { public void actionPerformed(ActionEvent e) { runFlag = !runFlag; } } class UpL implements ActionListener { public void actionPerformed(ActionEvent e) { int newPriority = getPriority() + 1; if(newPriority > Thread.MAX_PRIORITY) newPriority = Thread.MAX_PRIORITY; setPriority(newPriority); } } class DownL implements ActionListener { public void actionPerformed(ActionEvent e) { int newPriority = getPriority() - 1; if(newPriority < Thread.MIN_PRIORITY) newPriority = Thread.MIN_PRIORITY; setPriority(newPriority); } } public void run() { while (true) { if(runFlag) { t.setText(Integer.toString(count++)); pr.setText( Integer.toString(getPriority())); } yield(); } } }

public class Counter5 extends JApplet { private JButton start = new JButton("Start"), upMax = new JButton("Inc Max Priority"), downMax = new JButton("Dec Max Priority"); private boolean started = false; private static final int SIZE = 10; private Ticker2[] s = new Ticker2[SIZE]; private JTextField mp = new JTextField(3); public void init() { Container cp = getContentPane(); cp.setLayout(new FlowLayout()); for(int i = 0; i < s.length; i++) s[i] = new Ticker2(cp); cp.add(new JLabel( "MAX_PRIORITY = " + Thread.MAX_PRIORITY)); cp.add(new JLabel("MIN_PRIORITY = "


+ Thread.MIN_PRIORITY)); cp.add(new JLabel("Group Max Priority = ")); cp.add(mp); cp.add(start); cp.add(upMax); cp.add(downMax); start.addActionListener(new StartL()); upMax.addActionListener(new UpMaxL()); downMax.addActionListener(new DownMaxL()); showMaxPriority(); // Recursively display parent thread groups:

ThreadGroup parent = s[0].getThreadGroup().getParent(); while(parent != null) { cp.add(new Label( "Parent threadgroup max priority = "

+ parent.getMaxPriority())); parent = parent.getParent(); } } public void showMaxPriority() { mp.setText(Integer.toString( s[0].getThreadGroup().getMaxPriority())); } class StartL implements ActionListener { public void actionPerformed(ActionEvent e) { if(!started) { started = true; for(int i = 0; i < s.length; i++) s[i].start(); } } } class UpMaxL implements ActionListener { public void actionPerformed(ActionEvent e) { int maxp = s[0].getThreadGroup().getMaxPriority(); if(++maxp > Thread.MAX_PRIORITY) maxp = Thread.MAX_PRIORITY; s[0].getThreadGroup().setMaxPriority(maxp); showMaxPriority(); } } class DownMaxL implements ActionListener { public void actionPerformed(ActionEvent e) { int maxp = s[0].getThreadGroup().getMaxPriority(); if(--maxp < Thread.MIN_PRIORITY) maxp = Thread.MIN_PRIORITY; s[0].getThreadGroup().setMaxPriority(maxp); showMaxPriority(); } } public static void main(String[] args) { Console.run(new Counter5(), 450, 600); } } ///:~

Ticker2 следует установленной раннее в данной главе форме, но здесь есть дополнительное JTextField для отображения приоритета процесса и две дополнительные кнопки для увеличения и уменьшения значения приоритета.

Также обратите внимание на использование yield() добровольно отдающему блок управления планировщику. Без этого механизм с множеством процессов также будет работать, но вы заметите, что все будет выполняться медленнее (удалите вызов yield( ) чтобы убедиться в этом). Можно также вызывать sleep( ), но тогда значение счетчика будет определяться продолжительностью задержки заданной при вызове sleep( ), а не приоритетом процесса.



Метод init( ) в Counter5 создает массив из десяти Ticker2, их кнопки и поля ввода размещаются на форме конструктором Ticker2. Counter5 добавляет кнопки для общего запуска, а также кнопки для увеличения и уменьшения максимального значения приоритета для группы процессов. Добавочно существуют строки (label), для отображения возможных максимальных и минимальных значений приоритетов для процесса и JTextField, для отображения максимального приоритета для группы (мы рассмотрим группу процессов в следующем разделе). В заключении всего, приоритеты групп процессов потомков также отображаются как строки (labels).

Когда нажимается кнопка "up" или "down", то выбирается приоритет этого Ticker2 и он, соответственно, увеличивается или уменьшается.

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

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

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


Содержание раздела