Showing posts with label Threads. Show all posts
Showing posts with label Threads. Show all posts

Sunday, May 23, 2021

Multi thread and Concurrency - join

<p>In this coding exercise we will you all the knowledge from the previous lectures. <br>Before taking the exercise make sure you review the following topics in particular:<br>1. Thread Creation - how to create and start a thread using the <code>Thread</code> class and the <code>start()</code> method.</p>


<p>2. Thread Join - how to wait for another thread using the <code>Thread.join()</code> method.</p>


<p>In this exercise we will efficiently calculate the following <code>result = base1 ^ power1 +&nbsp;base2 ^ power2</code></p>


<p>Where <code>a^b</code> means: <em>a</em> raised to the power of <em>b. </em></p>

<p>For example <code>10^2 = 100</code></p>

<p>We know that raising a number to a power is a complex computation, so we we like to execute:</p>

<p><code>result1 = x1 ^ y1</code></p>

<p><code>result2 = x2 ^ y2</code></p>

<p>In parallel.</p>

<p>and combine the result in the end : <code>result = result1 +&nbsp;result2</code></p>

<p>This way we can speed up the entire calculation.</p>



-------------------------------------------------


package thread.example;

import java.math.BigInteger;

public class ComplexCalculation {
public static void main(String[] args) {
ComplexCalculation c = new ComplexCalculation();
BigInteger result = c.calculateResult(new BigInteger("2"),new BigInteger("2"),new BigInteger("2"),new BigInteger("3"));
System.out.println(result);
}
public BigInteger calculateResult(BigInteger base1, BigInteger power1, BigInteger base2, BigInteger power2) {
BigInteger result;
/*
Calculate result = ( base1 ^ power1 ) + (base2 ^ power2).
Where each calculation in (..) is calculated on a different thread
*/
PowerCalculatingThread one = new PowerCalculatingThread(base1, power1);
PowerCalculatingThread two = new PowerCalculatingThread(base2, power2);
one.start();
two.start();

try {
one.join();
two.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
result = one.getResult().add(two.getResult());
return result;
}

private static class PowerCalculatingThread extends Thread {
private BigInteger result = BigInteger.ONE;
private BigInteger base;
private BigInteger power;

public PowerCalculatingThread(BigInteger base, BigInteger power) {
this.base = base;
this.power = power;
}

@Override
public void run() {
/*
Implement the calculation of result = base ^ power
*/
this.result = this.base.pow(this.power.intValue());

// result = BigInteger.ONE;
//
// for(BigInteger i = BigInteger.ZERO;
// i.compareTo(power) !=0;
// i = i.add(BigInteger.ONE)) {
// result = result.multiply(base);
// }
}

public BigInteger getResult() {
return result;
}
}

} 


2. Thread Join - how to wait for another thread using the Thread.join() method.

In this exercise we will efficiently calculate the following result = base1 ^ power1 + base2 ^ power2

Where a^b means: a raised to the power of b.

For example 10^2 = 100

We know that raising a number to a power is a complex computation, so we we like to execute:

result1 = x1 ^ y1

result2 = x2 ^ y2


In parallel.

and combine the result in the end : result = result1 + result2

This way we can speed up the entire calculation.


Note :

base1 >= 0, base2 >= 0, power1 >= 0, power2 >= 0

Friday, May 21, 2021

Multi thread and Concurrency - Interruption 3 samples

 

public class Main1 {

    public static void main(String [] args) {

        Thread thread = new Thread(new BlockingTask());


        thread.start();

    }


    private static class BlockingTask implements Runnable {


        @Override

        public void run() {

            //do things

            try {

                Thread.sleep(500000);

            } catch (InterruptedException e) {

                System.out.println("Existing blocking thread");

            }

        }

    }

}

-----------------------------------


import java.math.BigInteger;


/**

 * Thread Termination & Daemon Threads

 * 

 */

public class Main2 {


    public static void main(String[] args) {

        Thread thread = new Thread(new LongComputationTask(new BigInteger("200000"), new BigInteger("100000000")));


        thread.start();

        thread.interrupt();

    }


    private static class LongComputationTask implements Runnable {

        private BigInteger base;

        private BigInteger power;


        public LongComputationTask(BigInteger base, BigInteger power) {

            this.base = base;

            this.power = power;

        }


        @Override

        public void run() {

            System.out.println(base + "^" + power + " = " + pow(base, power));

        }


        private BigInteger pow(BigInteger base, BigInteger power) {

            BigInteger result = BigInteger.ONE;


            for (BigInteger i = BigInteger.ZERO; i.compareTo(power) != 0; i = i.add(BigInteger.ONE)) {

// without this interruption, this won't be interrupt

                if (Thread.currentThread().isInterrupted()) {

                    System.out.println("Prematurely interrupted computation");

                    return BigInteger.ZERO;

                }

                result = result.multiply(base);

            }


            return result;

        }

    }

}


------------------------------------------


import java.math.BigInteger;


/**

 * Thread Termination & Daemon Threads

 * 

 */

public class Main3 {


    public static void main(String[] args) throws InterruptedException {

        Thread thread = new Thread(new LongComputationTask(new BigInteger("200000"), new BigInteger("100000000")));


// make thread deamon, run in background

        thread.setDaemon(true);

        thread.start();

        Thread.sleep(100);

        thread.interrupt();

    }


    private static class LongComputationTask implements Runnable {

        private BigInteger base;

        private BigInteger power;


        public LongComputationTask(BigInteger base, BigInteger power) {

            this.base = base;

            this.power = power;

        }


        @Override

        public void run() {

            System.out.println(base + "^" + power + " = " + pow(base, power));

        }


        private BigInteger pow(BigInteger base, BigInteger power) {

            BigInteger result = BigInteger.ONE;


            for (BigInteger i = BigInteger.ZERO; i.compareTo(power) != 0; i = i.add(BigInteger.ONE)) {

                result = result.multiply(base);

            }


            return result;

        }

    }

}


Multi thread and Concurrency - Questions

 Question 4:

Observe the following code:


    public static void main(String [] args) {

        Thread thread = new Thread(new WaitingForUserInput());

        thread.setName("InputWaitingThread");

        thread.start();

    }

 

    private static class WaitingForUserInput implements Runnable {

        @Override

        public void run() {

            try {

                while (true) {

                    char input = (char) System.in.read();

                    if(input == 'q') {

                        return;

                    }

                }

            } catch (IOException e) {

                System.out.println("An exception was caught " + e);

            };

        }

    }

Please choose the correct statement:


1. <p>We simply need to add <code>thread.interrupt();</code>&nbsp; in the end of the <code>main</code> method, which will stop the <code>"InputWaitingThread"</code> thread.</p>


2. <p>We simply need to add <code>thread.interrupt();</code>&nbsp; in the end of the <code>main</code> method, which will stop the <code>"InputWaitingThread"</code> thread.</p>

<p>And also add a new <code>catch</code> block in the <code>run</code> method inside the <code>WaitingForUserInput</code>, to handle an <code>InterruptedException</code>, and exit from the thread in that block of code.


3.

 <p>The only ways to stop the application are:</p>

 <p>1. For the user to type in the letter 'q'.</p>

    2. Set <code>thread.setDaemon(true);</code></p> in the main method, before starting the thread

 We simply need to add <code>thread.interrupt();</code> &nbsp; in the end of the<code>main</code> method, which will stop the <code>"InputWaitingThread"</code> thread.

 <p>3. Forcefully kill the application</p>

 

4. <p>The application will stop immediately, since there is no <code>Thread.sleep()</code> call in the main method. And as soon as the <code>main</code> method exits, the application terminates. </p>



Question 2:

    public static void main(String [] args) {

        Thread thread = new Thread(new SleepingThread());

        thread.start();

        thread.interrupt();

    }

 

    private static class SleepingThread implements Runnable {

        @Override

        public void run() {

            while (true) {

                try {

                    Thread.sleep(1000000);

                } catch (InterruptedException e) {

                }

            }

        }

    }

Please choose the correct statement



1. <p>The application will stop anyway, when the main thread runs out of instructions to execute.</p>

2. <p>The application will terminate as soon as the <code>thread.interrupt();</code> code is executed.</p>

3. <p>Without modifying the code, the application will not stop.<br>We need to add a <code>return;</code> statement inside the <code>catch (InterruptedException e)</code> block to stop the application.</p>

4. 



Answer

Q1 - 3

Q2 - 3


Q2

That's correct, the only way to programmatically stop the application is to make the thread a daemon. Unfortunately System.in.read() does not respond to Thread.interrupt();

Q2

That is correct. As a rule of thumb, never leave a catch block empty, and use the InterruptedException catch block to gracefully stop the current thread (by adding some print or cleaning code before returning from the run method)


Multi thread and Concurrency - Simple MultiExecutor

 Very simple code block of MultiExecutor class


package thread.example;

import java.util.ArrayList;
import java.util.List;

/**
* <p>The client of this class will create a list of <code>Runnable</code> tasks and
 provide that list into <code>MultiExecutor</code>'s constructor.</p>
* <p>When the client runs the&nbsp; <code>executeAll()</code>,&nbsp;
the <code>MultiExecutor</code>,&nbsp; will execute all the given tasks.</p>
* <p>To take full advantage of our multicore CPU, we would like the
<code>MultiExecutor</code> to execute all the tasks in parallel, 
by passing each task to a different thread.</p>
*/
public class MultiExecutor {

// Add any necessary member variables here
private final List<Runnable> tasks;

/*
* @param tasks to executed concurrently
*/
public MultiExecutor(List<Runnable> tasks) {
// Complete your code here
this.tasks = tasks;
}

/**
* Starts and executes all the tasks concurrently
*/
public void executeAll() {
// complete your code here
// create list of threads
List<Thread> threads = new ArrayList<>(tasks.size());
// for each task create a thread and add to thread list.
for (Runnable task : tasks) {
Thread thread = new Thread(task);
threads.add(thread);
}

// start each thread
for (Thread thread : threads) {
thread.start();
}
}
}

Multi thread and Concurrency - Questions

Q1.Why do we want to use multiple threads in an application?


  1. The more threads in one application, the faster the application will be.
  2. By using multiple threads we can execute multiple related tasks simultaneously, making the application more responsive. And executing multiple tasks in parallel may achieve higher performance.
  3. Having multiple threads is always a better software design.
  4.  Creating more threads in one process, is always better than creating a new application.


Q2. Multiple threads in a single process share:


  1. The stack , heap , instruction pointer, Code,  The process's open files
  2. Only application code
  3. The heap, Code, The process's open files, The process's meta data
  4. Only heap


Q3. How does the Operating System design what thread to schedule?

  1. The Operating System maintains a dynamic priority for each thread to prioritize interactive threads and to avoid starvation for any particular thread in the system.
  2. The Operating System is going to choose the interactive threads ahead of any other threads at all times to make the users happy.
  3. The Operating System will always pick the shortest job at any given moment.
  4. The Operating System will simply pick a random thread to execute, which on average will be fair to everybody.

 

Q1 - 2

Q2 - 3

Q3 - 1

Multi thread and Concurrency - Context Switch , Thread scheduling and Thread vs Process

In simple scenario

  • We have lots of processes
  • Each process having one or more thread
  • with One CPU


Threads are fighting to get CPU

stop one thread and allow another thread to run, this switch between thread in simple Context switch


The price for context switch --> price for concurrency( multi task)

  • store data for one thread
  • restore data for resume thread

Important

  • Too many thread -> spend more time in management than real productive work
  • Thread consume less resources compare to process
  • context switch between two thread in same process is cheaper than context switch between two thread in different process


Thread scheduling 

  • if we give queue (FIFO) --> 

    longer thread comes first, then other thread has to wait long time - starvation


  • How about scheduling shorter one first --> 

    then longer tasks may not get a chance

Now we have little understanding of trade-off and challenges in scheduling Thread


In general OS divide time into moderately sized pieces called 'epochs'

In each epochs -> OS allocate different time slice for each thread

Note: not each thread can complete in epochs

decision to allocate time for thread --> based on dynamic priority ( OS maintain for each thread)

static priority -> developer set ahead of time

bonus -> adjusted by OS


This way OS will give preference to interactive and  real time threads ( these need immediate attention)

will give preference to computational threads that did not complete or |  did not get enough time to run in previous epics to prevent "starvation"


Dynamic Priority = Static Priority + Bonus

bonus - can be negative


when to use multi thread in single program

when to create a new program an run differently 


When to preference multi thread architecture

  • when task share lots of data
  • Threads are much faster create and destroy
  • switch between threads of same process is much faster

lastly we create separate process and run 

If Security and stability are higher importance

Tasks are unrelated to each other -> no point putting them in same process


https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.State.html

https://developer.ibm.com/tutorials/l-completely-fair-scheduler/

Multi thread and Concurrency - Basic Understanding

 Multi thread - Why we need

  1.  Responsiveness
  2.  Performance

Multi thread, Synchronous and Asynchronous, one of the words you will here a lot.

let's take a simple example

In a supermarket people come and buy product and go to queue and purchase. In a simple scenario, there is one person who buys a large number of items and one with few items. If the customer with large items comes, other has to wait for a huge time. 

So can we reduce this ? IF yes --> How ?

In an application we have basically two parts. UI and backend

Looking at that point Responsiveness is more important to UI and Performance in backend. This is where threads become handy


Concurrency -  Multi tasking

  • Achieved by multitasking between threads
  • Concurrency == Multi tasking

Note: Even with one core we can achieve multitasking

One core -> multiple tasks concurrently

more cores -> multiple tasks parallelly


Performance Impact

  • Completing a complex task much faster
  • Finish more work in the same period of time
  • For high scale services
    • Fewer machines
    • Less money spent on hardware
    • More money save | money in pocket


Thread is a part of process and Process may have few components like

  • Process Specific
    • PID - process Id
    • Mode
    • Priority  etc
  • Files
  • Data (Heap)
  • Code
  • Thread (  there can be one or more threads)

each Thread will have

  • Stack
  • Instruction Pointer

Note: Thread will have its unique stack and Instruction pointer , but rest of the items are shared with in process context


Stack -> Region in memory, where local variables are stored, and passed in to functions

Instruction pointer -> Address of the next instruction to execute


Why we have its own stack and Instruction pointer ?

at given time each thread is executing different instructions in a different function 


Summary up to now

Why multi thread ?

Responsiveness achieved by concurrency

Performance achieved by parallelism

Thread

Stack

Instruction pointer

What thread share

files

heap(data)

code

Tuesday, May 20, 2014

Ruannable vs Callable



"The Callable interface is similar to Runnable, in that both are designed for classes whose instances are potentially executed by another thread. A Runnable, however, does not return a result and cannot throw a checked exception."

RunnableCallable>
Introduced in Java 1.0Introduced in Java 1.5 as part of java.util.concurrent library
Runnable cannot be parametrized Callable is a parametrized type whose type parameter indicates the return type of its run method
Classes implementing Runnable needs to implement run() methodClasses implementing Callable needs to implement call() method
Runnable.run() returns no ValueCallable.call() returns a value of Type T
Can not throw Checked ExceptionsCan throw Checked Exceptions
public class RunnableTest implements Runnable {
              @Override
              public void run() {
                         //any processing
              }
}
import java.util.concurrent.Callable;


public class CallableTest implements Callable { 
          @Override 
           public String call() throws Exception { 
                      // any processing
                    return new String("I am Callable and can return value and throw checked exception"); 
              } 
}

Tuesday, June 23, 2009

Multi threads

following code creates a single Runnable instance and three Thread instances. All three Thread instances get the same Runnable instance. All threads are given unique names.
Finally, all three threads are started by invoking strat();

Thread class(Runnable Instance)
---------------------------------

public class NameRunnable implements Runnable
{
public void run()
{
for( int i =1; i<4 ;i++ )
{
System.out.println( "Run by : "+Thread.currentThread().getName() );
}
}
}

main class
----------

public class ManyNames
{
public static void main( String[] args )
{
NameRunnable nr = new NameRunnable();
Thread one = new Thread(nr);
one.setName( "One");
Thread two = new Thread(nr);
two.setName( "two");
Thread three = new Thread(nr);
three.setName( "three");
one.start();
two.start();
three.start();

}
}


result
--------

Run by : One
Run by : One
Run by : One
Run by : three
Run by : three
Run by : three
Run by : two
Run by : two
Run by : two

or

Run by : three
Run by : two
Run by : three
Run by : One
Run by : three
Run by : two
Run by : One
Run by : two
Run by : One

we can't decide the output. Schedular decides the threads execution time and order and it is out of JVM control , more from OS


when call start, it makes new call stack

Daemon Thread and User Threads

In java we have two type of Threads : Daemon Thread and User Threads. Generally all threads created by programmer are user thread (unless you specify it to be daemon or your parent thread is a daemon thread). User thread are generally meant to run our programm code. JVM doesn't terminates unless all the user thread terminate.

On the other hand we have Daemon threads. Typically these threads are service provider threads. They should not be used to run your program code but some system code. These thread run paralley to your code but survive on the mercy of the JVM. When JVM finds no user threads it stops and all daemon thread terminate instantly. Thus one should never rely on daemon code to perform any program code.

For better understanding consider a well known example of Daemon thread : Java garbage collector. Garbage collector runs as a daemon thread to recalim any unused memory. When all user threads terminates, JVM may stop and garbage collector also terminates instantly.


--------------------

daemon threads are created by the JVM unlike normal threads which are created by the user.
The daemon threads provides services to the user-created threads and they run in the background.
Hence to set them u have to write threadname.setDaemon(true) and to check whether a thread is a daemon thread or not you write isDaemon().