*********************************************Y***Z

Download Report

Transcript *********************************************Y***Z

Threads II
• Thread Priorities
• The interrupt() method
• Threads Synchronization
• Thread Animation
• Examples – after each section
• Exercises
Unit 15
1
Thread Priority
•
Execution of multiple threads on a single CPU in some order is called scheduling.
•
The Java runtime environment supports a very simple, deterministic scheduling
algorithm called fixed-priority scheduling. This algorithm schedules threads on the
basis of their priority relative to other Runnable threads.
•
Thread priorities are integers ranging between MIN_PRIORITY and
MAX_PRIORITY (constants defined in the Thread class).
•
At any given time, when multiple threads are ready to be executed, the runtime
system chooses for execution the Runnable thread that has the highest priority.
•
If two threads of the same priority are waiting for the CPU, the scheduler arbitrarily
chooses one of them to run.
Unit 15
2
Thread Priority
• The values of constants in java.lang.Thread are as follows:
public static final int
MAX_PRIORITY
10
public static final int
MIN_PRIORITY
1
public static final int
NORM_PRIORITY
5
• The methods int getPriority() and setPriority(int priority) are used the accessor and
mutator methods used for the priority of a Java thread.
• The default priority value of a thread is 5 (java.lang.NORM_PRIORITY) or it is
the priority of the thread that constructed it.
Unit 15
3
Thread Priority – Example 1
1.
public class SimplePThread extends Thread {
2.
3.
public SimplePThread(String str) {
4.
super(str); //Thread can be created using a string
5.
}
6.
public void run() {
7.
for (int i = 1; i < 400; i++) {
8.
for(int j = 0; j < 40000; j++)
9.
System.out.print(""); //Keeps thread busy
10.
System.out.print(getName());
11.
}
12.
System.out.print(".");
13.
}
14.
public static void main (String[] args) {
15.
16.
Thread t1 = new SimplePThread("1");
17.
Thread t2 = new SimplePThread("2");
18.
19.
t1.setPriority(Thread.NORM_PRIORITY + 1);
20.
t2.setPriority(Thread.NORM_PRIORITY - 1);
21.
22.
System.out.println("Thread 1 has priority " + t1.getPriority());
23.
System.out.println("Thread 2 has priority " + t2.getPriority());
24.
25.
t1.start(); t2.start();
26.
}
27. }
Unit 15
4
The interrupt() method
•
The interrupt() method (public void interrupt()) interrupts the current thread. If thread is
inactive, an InterruptedException is thrown which must be caught.
•
The isInterrupted() method (public boolean isInterrupted()) checks if the current thread
is interrupted or not.
•
An example shows their use.
Unit 15
5
Example 2
1.
2.
import javax.swing.*;
import java.awt.event.*;
3. public class TimeThread3 extends JFrame implements ActionListener {
4.
5.
private JTextField sec, min, hrs; private JButton button; private JPanel panel;
6.
7.
private TimerTh t; private int time = 0;
8.
9.
public TimeThread3()
10.
{
11.
super("Time");
12.
13.
sec = new JTextField(3); sec.setEditable(false);
14.
min = new JTextField(3); min.setEditable(false);
15.
hrs = new JTextField(3); hrs.setEditable(false);
16.
17.
button = new JButton("Stop"); button.addActionListener(this);
18.
19.
panel = new JPanel(); panel.add(hrs); panel.add(min); panel.add(sec);panel.add(button);
20.
getContentPane().add(panel); pack(); setVisible(true);
21.
22.
t = new TimerTh(); t.start();
23.
}
Unit 15
6
Example 2 – Contd.
24. class TimerTh extends Thread //Inner Class
25. { public void run()
26.
{ try
27.
{
27.
while(true)
28.
{ Thread.sleep(1000); time++;
29.
sec.setText(time%60 + ""); //Display seconds
30.
min.setText((time - (time/3600)*3600)/60 + ""); //Display minutes
31.
hrs.setText(time/3600 + ""); //Display hours
32.
}
33.
} catch(InterruptedException e) { System.out.println("Timer Stops"); }
34.
}
35. }
•
Here the Thread appears as an Inner Class.
• Compare this with the example 2 of the previous lecture in which the thread was implemented
by implementing the Runnable interface.
• As an Inner Class the thread can access the textfields hrs, min and sec of the enclosing class.
•
Both usages are acceptable.
Unit 15
7
Example 2 – Contd.
36. public void actionPerformed(ActionEvent e)
37. {
38.
t.interrupt(); //Stop the timer
39.
if(t.isInterrupted()) //If successful,
40.
{
41.
JOptionPane.showMessageDialog(this,
42.
"Time stopped " + hrs.getText() + ":" + min.getText() + ":" + sec.getText());
42.
System.exit(0);
43.
}
44. }
45.
46. public static void main(String[] args) { new TimeThread3(); }
47. }
Unit 15
8
Thread Synchronization
•
When two or more threads access a shared resource, (for example a variable), the resource may
be corrupted e.g., unsynchronized threads accessing the same database
•
Such blocks of code are usually called critical sections and must be executed in a mutuallyexclusive way
•
When a block of Java code guarded by the synchronized keyword, it can be executed by
only one thread at any time
•
You can synchronize an entire method or just a few lines of code by using the synchronized
keyword
•
Note that code that is thread-safe (i.e, guarded by synchronized) is slower than code that is
not.
•
Next, we present an example which shows problems due to shared thread access and then the
synchronized thread version.
Unit 15
9
Example 2
class BankAccount
{ private int balance;
public BankAccount(int balance)
{ this.balance = balance; }
public class UnsafeBankAccount extends Thread{
BankAccount ba;
public UnsafeBankAccount(BankAccount ba)
{ this.ba = ba; }
public void doNothing()
{ depositWithdraw(10);
depositWithdraw(20);
depositWithdraw(30);
}
public void run()
{ System.out.println(getName()+" got balance: "+ba.get());
ba.doNothing();
System.out.println(getName()+" got balance: "+ba.get());
}
public void depositWithdraw(int money)
{ try
{ balance += money;
Thread.sleep((long)(Math.random()*1000));
balance -= money;
} catch(InterruptedException e){}
}
public static void main(String[] args ){
BankAccount ba = new BankAccount(0);
for(int i=0; i<9; i++)
new UnsafeBankAccount(ba).start();
}}
int get()
{ return balance; }
}
Unit 15
10
Thread Synchronization
•
When the program is executed, it may produce
erroneous output.
•
This is because many threads are executing
the method depositWithdraw(int money) and
get() at the same time.
•
So it may be possible that while one thread is
incrementing the variable balance, many
others are decreasing it and vice versa.
•
In the output snapshot shown here, at one
point the balance is 190 although practically
the user deposits and withdraws a maximum
amount of 30 each time.
Unit 15
11
Thread Synchronization
•
One solution to the problem pointed out is to use the synchronized keyword with all
methods that deal with the variable balance.
•
This is to ensure that only one thread accesses the variable balance at a time.
•
Other threads may wait() while one thread is accessing and modifying the variable
balance. The method wait() is inherited by the class java.lang.Thread from the class
java.lang.Object.
•
When the thread accessing and modifying the variable balance is done, it may
notifyAll() threads waiting to execute the synchronized methods.
•
The complete correct program appears on the next slide.
Unit 15
12
Example 3
class MyBankAccount
{
private int balance;
private boolean busy = false;
public class SafeBankAccount extends Thread{
MyBankAccount ba;
public SafeBankAccount(MyBankAccount ba)
{ this.ba = ba; }
public MyBankAccount(int balance)
{
this.balance = balance; }
public void doNothing()
{ depositWithdraw(10); depositWithdraw(20);
depositWithdraw(30);
}
public synchronized void depositWithdraw(int
money)
{ try
{ while(busy) wait();
busy = true; balance += money;
Thread.sleep((long)(Math.random()*1000));
balance -= money; busy = false;
notifyAll(); //notifies all waiting threads
} catch(InterruptedException e){}
}
public void run()
{
System.out.println(getName()+" got initial balance: "+
ba.get());
ba.doNothing();
System.out.println(getName()+" got final balance: "+
ba.get());
}
public static void main(String[] args ){
MyBankAccount ba = new MyBankAccount(0);
for(int i=0; i < 9; i++)
new SafeBankAccount(ba).start();
}
}
synchronized int get()
{ return balance; }
synchronized boolean busy()
{
return busy; }
}
13
Threads Animation
•
In addition to applications in accessing databases, threads can also be used to create
animations.
•
In the next example we show a program where a thread is used to create an
animation of a ball moving vertically.
•
The run() method increments the y coordinate of the ball to be drawn. If the ycoordinate exceeds the height of the window, the ball is reflected back by negating
the increment.
•
The complete program appears in the next slide.
Unit 15
14
Example 4 – Thread Animations
import java.awt.*;
import java.applet.Applet;
public class UpDown extends Applet implements
Runnable {
int radius, x, y;
Thread t;
public void run(){
int yDir = +1;
int incr = 10;
int sleepFor = 50;
while(true) {
y += (incr * yDir);
repaint();
public void init() {
radius = 20;
x = 30; //signifies x location
y = 20; //signifies y location
Thread t = new Thread(this);
t.start();
}
public void paint(Graphics g) {
g.setColor(Color.blue);
g.fillOval(x - radius, y - radius, 2*radius,
2*radius);
}
if(y - radius < incr ||
y + radius + incr > getSize().height)
yDir *= -1; //reflect the ball back
try{
t.sleep(sleepFor);
}catch(InterruptedException e) {}
} // end while
}
}
15
Exercises
Q. 1 In the first example replace the statement for(int j = 0; j < 40000; j++)
System.out.print(""); //Keeps thread busy with Thread.sleep(1000); Observe the
output and explain why it happens. What happens to thread priorities?
Q. 2 In Example 4, can the code to show the JOptionPane be included in the try …
catch(InterruptedException e){ …. } clause? Is such uasge acceptable?
Q. 3: In example 4, make the ball move in both horizontal and vertical directions.
Unit 15
16