Threads
Threads
• }
• }
• }
• for(int i=1;i<100;i++){
• for(int i=1;i<100;i++){
• System.out.println("ThreadC running");
• System.out.println("End of ThreadC");
• }
• }
• }
• ta.start();
• tb.start();
• tc.start();
• for(int j=0;j<40;j++){
• }
Implementing Runnable
• The easiest way to create a thread is to create a
class that implements the Runnable interface.
• To implement Runnable, a class need only
implement a single method called run(),
– Public void run()
• Inside run(), you will define the code that
constitutes the new thread.
• It is important to understand that run() can call
other methods, use other classes, and declare
variables, just like the main thread can
Continued…
• The only difference is that run() establishes the
entry point for another, concurrent thread of
execution within your program.
• This thread will end when run returns.
• After you create a class that implements Runnable,
you will instantiate an object type of Thread from
within that class.
• After the new thread is created , it will not start
running until you call its start() method, which is
declared within Thread.
Continued…
• Class NewThread implements Runnable{
• Thread T;
• NewThread(){
• T=new Thread(this,”Demo Thread”);
• System.out.println(“Child thread: “+ T);
• T.start();
• }
• Public void run(){
• try{
• for(int i=5;i>0;i--){
• System.out.println(“child thread:”+i)
• Thread.sleep(500);
• }
• }catch(InterruptedException e){
• System.out.println(“Child interrupted”);
• }
• System.out.println(“Exitiing child thread”);
• }
• }
• Public class ThreadDemo{
• Public static void main(String[] args){
• new NewThread();
• try{
• for(int i=5; i>0;i--){
• System.out.println(“Main thread: “+i);
• Thread.sleep(1000);
• }
• }catch(InterruptedException e){
• System.out.println(“Main thread interrupted”);
• }
• System.out.println(“Main thread exitiing”);
• }
THREAD PRIORITY
• In Java, all the thread instances the developer created have the
same priority, which the process will schedule fairly without
worrying about the order.
• Every Java thread has a priority that helps the operating system
determine the order in which threads are scheduled.
• It is important for different threads to have different priorities.
• It is possible to control the priority of the threads by using the
Java APIs.
• The Thread.setPriority(…) method serves this purpose.
• The Thread class provides 3 constants value for the priority:
• MIN_PRIORITY = 1, NORM_PRIORITY = 5, MAX_PRIORITY = 10
• The priority range of the thread should be between the
minimum and the maximum number.
Continued…
• class A extends Thread {
• public void run() {
• System.out.println(“Thread A started”);
• for(int i = 1; i <= 4; i++) {
• System.out.println(“\t From ThreadA: i= ” + i);
• }
• System.out.println(“Exit from A”);
• }
• }
• class B extends Thread {
• public void run() {
• System.out.println(“Thread B started”);
• for(int j = 1; j <= 4; j++) {
• System.out.println(“\t From ThreadB: j= ” + j);
• }
• System.out.println(“Exit from B”);
• }
• }
Continued…
• class C extends Thread {
• public void run() {
• System.out.println(“Thread C started”);
• for(int k = 1; k <= 4; k++) {
• System.out.println(“\t From ThreadC: k= ” + k);
• }
• System.out.println(“Exit from C”);
• }
• }
• public class ThreadPriorityDemo {
• public static void main(String args[]) {
• A threadA = new A();
• B threadB = new B();
• C threadC = new C();
Continued…
• threadC.setPriority(Thread.MAX_PRIORITY);
• threadB.setPriority(threadA.getPriority() + 1);
• threadA.setPriority(Thread.MIN_PRIORITY);
• System.out.println(“Started Thread A”);
• threadA.start();
• System.out.println(“Started Thread B”);
• threadB.start();
• System.out.println(“Started Thread C”);
• threadC.start();
• System.out.println(“End of main thread”);
• }
• }
Thread Synchronization
• Threading is a very powerful technique which
is sometimes very hard to control, especially
when it is accessing shared resources.
• In such cases, the threads have to be
coordinated, otherwise it will violate the data
of the whole application.
Continued…
• For example, a printer cannot be used to print
two documents at the same time and if there
are multiple printing requests, threads
managing these printing operations needs to be
coordinated.
• Another example would be simultaneously
operating the same bank account: it is not
correct to do both deposit and withdraw
operations on a bank account at the same time.
Continued…
• When two or more threads need access to a
shared resource, they need some way to
ensure that the resource will be used by only
one thread at a time.
• The process by which this is achieved is called
synchronization.
Read/Write Problem
• If one thread tries to read the data and another
thread tries to update the same data, it is known
as read/ write problem, and it leads to inconsistent
state for the shared data.
• This can be prevented by synchronizing access to
the data via Java synchronized keyword. For
example,
public synchronized void update() {
…
}
Continued…
• It is better to explain the synchronized
approach to access the shared data via a
simple example.
• Consider an example of a bank offering online
access to its customers to perform
transactions on their accounts from anywhere
in the world
Continued…
• If the cheque-receipient happens to withdraw
the money at the same time the original-
account holder deposits the money, both
parties are performing simultaneous
operations on the same account.
• This situation can lead to incorrect operation
on the account
Continued…
• This can be avoided by synchronization, which
ensures that only one person is able to
perform an operation on a shared data at a
time (i.e., in a way operations are sequenced
to avoid data inconsistency problems).
• The following class shows a typical invocation
of banking operations via multiple threads
Synchronization Example
• public class InternetBankingSystem {
• public static void main(String [] args ) {
• Account accountObject = new Account(100);
• new Thread(new DepositThread(accountObject,30)).start();
• new Thread(new DepositThread(accountObject,20)).start();
• new Thread(new DepositThread(accountObject,10)).start();
• new Thread(new WithdrawThread(accountObject,30)).start();
• new Thread(new WithdrawThread(accountObject,50)).start();
• new Thread(new WithdrawThread(accountObject,20)).start();
• } // end main()
• }
Continued…
• public class WithdrawThread implements Runnable {
• private Account account;
• private double amount;
• public WithdrawThread(Account account, double amount) {
• this.account = account;
• this.amount = amount;
• }
• public void run() {
• //make a withdraw
• account.withdraw(amount);
• }
• }//end WithdrawThread class
Continued…
• public class DepositThread implements Runnable {
• private Account account;
• private double amount;
• public DepositThread(Account account, double amount) {
• this.account = account;
• this.amount = amount;
• }
• public void run() {
• //make a deposit
• account.deposit(amount);
• }
• }//end DepositThread class
Continued…
• public class Account {
• private double balance = 0;
• public Account(double balance) {
• this.balance = balance;
• }
• // if ‘synchronized’ is removed, the outcome is unpredictable
• public synchronized void deposit(double amount) {
• if (amount < 0) {
• throw new IllegalArgumentException(“Can’t deposit.”);
• }
• this.balance += amount;
• System.out.println(“Deposit ”+amount+“ in thread” +Thread.currentThread().getId()
• +“, balance is ” +balance);
• }
• // if ‘synchronized’ is removed, the outcome is unpredictable
• public synchronized void withdraw(double amount) {
• if (amount < 0 || amount > this.balance) {
• throw new IllegalArgumentException(“Can’t withdraw.”);
• }
• this.balance -= amount;
• System.out.println(“Withdraw ”+amount+“ in thread ” + Thread.currentThread().getId()
• + “, balance is ”+balance);
• }
• }//end Account class
Continued…
• There are 6 threads that access the same Account
object simultaneously.
• As can be seen, the three deposit threads are
performing deposit operations on an account and
simultaneously three Withdraw threads are
withdrawing from the same account.
• If the account object is not synchronized properly,
the outcome may be unpredictable while these
operations are performing simultaneously.
• To ensure the proper behavior of the application, it
is necessary to synchronize the methods on the
Account class.
Continued…
• The synchronized method will ensure that only
one class can access the data at one time,
other operations have to wait until the first
operation finishes.
• However, if the account class is modified
without the synchronized keyword placed on
the methods that access the balance data,
unpredictable behavior will occur.
If you use Thread class
• public class WithdrawalThread extends Thread {
• private Account account;
• private double amount;
• public WithdrawalThread(Account account, double amount) {
• this.account = account;
• this.amount = amount;
• }
• public void run() {
• //make a withdraw
• account.withdrawal(amount);
• }
• }//
Continued…
• public class DepositThread extends Thread {
• private Account account;
• private double amount;
• public DepositThread(Account account, double amount) {
• this.account = account;
• this.amount = amount;
• }
• public void run() {
• //make a deposit
• account.deposit(amount);
• }
• }//end DepositThread class
Continued…
• public class Account {
• private double balance = 0;
• public Account(double balance) {
• this.balance = balance;
• }
• // if ‘synchronized’ is removed, the outcome is unpredictable
• public synchronized void deposit(double amount) {
• if (amount < 0) {
• throw new IllegalArgumentException("Can’t deposit.");
• }
• this.balance += amount;
• System.out.println("Deposit "+amount+" in thread“ +Thread.currentThread().getId()
• +", balance is " +balance);
• }
• // if ‘synchronized’ is removed, the outcome is unpredictable
• public synchronized void withdrawal(double amount) {
• if (amount < 0 || amount > this.balance) {
• throw new IllegalArgumentException("Can’t withdraw.");
• }
• this.balance -= amount;
• System.out.println("Withdrawal "+amount+" in thread “ + Thread.currentThread().getId()
• + ", balance is "+balance);
• }
• }//end Account class
Continued..
• public class InternetBankingSystem {
• public static void main(String[] args) {
• Account accountObject = new Account(100);
• dt1.start();
• dt2.start();
• dt3.start();
• wt1.start();
• wt2.start();
• wt3.start();
• } // end main()
• }