unit 151 threads ii thread priorities the interrupt() method threads synchronization thread...
Post on 20-Dec-2015
254 views
TRANSCRIPT
Unit 15 1
Threads II
• Thread Priorities
• The interrupt() method
• Threads Synchronization
• Thread Animation
• Examples – after each section
• Exercises
Unit 15 2
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 3
Thread Priority
• The values of constants in java.lang.Thread are as follows:
• 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.
public static final int MAX_PRIORITY 10
public static final int MIN_PRIORITY 1
public static final int NORM_PRIORITY 5
Unit 15 4
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 busy10. 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 5
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 6
Example 2
1. import javax.swing.*;2. 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 7
Example 2 – Contd.
24. class TimerTh extends Thread //Inner Class25. { public void run()26. { try 27. {27. while(true)28. { Thread.sleep(1000); time++;29. sec.setText(time%60 + ""); //Display seconds30. min.setText((time - (time/3600)*3600)/60 + ""); //Display minutes31. hrs.setText(time/3600 + ""); //Display hours32. }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 8
Example 2 – Contd.
36. public void actionPerformed(ActionEvent e)37. {38. t.interrupt(); //Stop the timer39. 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 9
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 mutually-exclusive 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 10
Example 2class BankAccount
{ private int balance;
public BankAccount(int balance)
{ this.balance = balance; }
public void doNothing()
{ depositWithdraw(10);
depositWithdraw(20);
depositWithdraw(30);
}
public void depositWithdraw(int money)
{ try
{ balance += money;
Thread.sleep((long)(Math.random()*1000));
balance -= money;
} catch(InterruptedException e){}
}
int get()
{ return balance; }
}
public class UnsafeBankAccount extends Thread{
BankAccount ba;
public UnsafeBankAccount(BankAccount ba)
{ this.ba = ba; }
public void run()
{ System.out.println(getName()+" got balance: "+ba.get());
ba.doNothing();
System.out.println(getName()+" got balance: "+ba.get());
}
public static void main(String[] args ){
BankAccount ba = new BankAccount(0);
for(int i=0; i<9; i++)
new UnsafeBankAccount(ba).start();
} }
Unit 15 11
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 12
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.
13
Example 3class MyBankAccount{ private int balance; private boolean busy = false; 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){} } synchronized int get() { return balance; } synchronized boolean busy() { return busy; } }
public class SafeBankAccount extends Thread{ MyBankAccount ba; public SafeBankAccount(MyBankAccount ba) { this.ba = ba; } 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(); } }
Unit 15 14
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 y-coordinate exceeds the height of the window, the ball is reflected back by negating the increment.
• The complete program appears in the next slide.
15
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 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);
}
public void run(){
int yDir = +1;
int incr = 10;
int sleepFor = 50;
while(true) {
y += (incr * yDir);
repaint();
if(y - radius < incr ||
y + radius + incr > getSize().height)
yDir *= -1; //reflect the ball back
try{
t.sleep(sleepFor);
}catch(InterruptedException e) {}
} // end while
}
}
Unit 15 16
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.