Many programs contain code segments that are more or less in dependent of one another, and that may execute more efficiently if the code segments could be overlapped in time.

What is multitasking?

There are two types of multi-tasking programs.

Process based: Executing multiple programs/processes at the same time

Thread based: Single program can have many threads executing at same time, thread has less overhead than a process as threads share the same memory space

A multithreaded program contains two or more parts that can run concurrently. Each part of the program is called thread and each thread defines a separate path of execution. Multithreading is a specialized form of multitasking

Concurrency and Parallelism

Concurrent multithreading systems give the appearance of several tasks executing at once, but these tasks are actually split up into chunks that share the processor with chunks from other tasks. In parallel systems, two tasks are actually performed simultaneously. Parallelism requires a multi-CPU system.

Java Threads

Java threads are managed by the JVM. Java threads may be created by:

  • Extending Thread class
  • Implementing the Runnable interface

Extending Thread Class

To create a thread, you can extend the thread class and override its “run()” method.

For example,

public class MyThread extends Thread {
       public void run() {
         for (int i=0; i<10; i++) {
           System.out.println(“Hello world #“+i );
       }
    }
    ...
}
myThread t = new MyThread();

Above you can see a simple program that prints hello world 10 times using thread class.

To launch, or spawn, a thread, you just call the thread’s start() method. Don’t call the run() method directly to launch a thread. The start() method, which you should not override,  does all the thread launching. It launches a thread that starts its execution by calling the run() method.

In simple words,

  • when you want to create a thread, you’ll write code in run() method.
  • when you want to run a thread, you’ll call the start() method.

See antoher example below:

public class MyThread extends Thread {
    public void run() {
           for (int i=0; i           System.out.println(“Hello world #“+i);       } }
}
public class MyProgram {
   public MyProgram() {
        MyThread t = new MyThread();
        t.start();
    }
  public static void main(String args[]) {
     MyProgram p = new MyProgram();
  }
}

The previous program runs as a Java process that is, a thread running inside the JVM. When the start() method is called, the main thread creates a new thread. We now have two threads.

  • The main thread
  • The newly created thread

Both threads are running. The main thread doesn’t do anything. The new thread prints messages to screen and exits. When both threads are finished, then the process terminates

What is the Main Thread?

When a java program starts, one thread begins running immediately. This is usually called the main thread of your program, because it is the one that is executed when your program begins. The main thread is important for two reasons. It is a thread from which other child threads can be spawned. Often it is the last thread to finish execution because it performs various shutdown activities. Although the main thread starts automatically when the program is started, it can be controlled through a Thread object. We can do this by calling the currentThread() method, which is a public static member of class Thread. This method returns a reference to the thread in which it is called. Once you have the reference you can control the thread like any other thread.

Example:

public class myThread extends Thread {
    public void run() {
       for (int i=0; i           System.out.println(“Hello world #“+i);
    }}
public class MyProgram {
  public MyProgram() {
     MyThread t = new MyThread();
      t.start();
      for (int i=0; i          System.out.println(“Beep ”+i);
  }
  public static void main(String args[]) {
     MyProgram p = new MyProgram();
  }
}

Thread Lifecycle

Thread exists in several states.

  • A thread can be running
  • It can be ready to run as soon as it gets the CPU
  • A running thread can be suspended, which temporarily suspends its activity
  • A thread can be blocked when waiting for a resource.
  • At any time a thread can be terminated, which halts its execution immediately. Once terminated it cannot be resumed

Example:

public class Test{
public static void main(String args[]){

	Thread t = Thread.currentThread();
	System.out.println("Current Thread: " + t);

	//change the name of current thread
	t.setName("My Thread");
	System.out.println("After name change: " + t);

	try{
		for(int n=5;n>0;n--){
			System.out.println(n);
			Thread.sleep(1000);
		}
	}catch (InterruptedException ie){
		System.out.println("Main thread interrupted!");
	}
}
}

Example output:

Current Thread: Thread[main,5,main]
After name change: Thread[My Thread,5,main]
5
4
3
2
1
(Note: above result might vary from system to system)
 

Extending Thread Example

public class TryThread extends Thread {
String firstName;
String secondName;
Long aWhile;
  public TryThread(String firstName, String secondName, long delay) {
    this.firstName = firstName;      // Store the first name
    this.secondName = secondName;    // Store the second name
    aWhile = delay;                  // Store the delay
    setDaemon(true);                 // Thread is daemon
  }
public void run() {
    try {
      while(true) {                          // Loop indefinitely...
        System.out.print(firstName);         // Output first name
        sleep(aWhile);                       // Wait aWhile msec.
        System.out.print(secondName + "\n"); // Output second name
      }
    } catch(InterruptedException e) {        // Handle thread interruption
      System.out.println(firstName + secondName + e);     // Output the exception
    }
  }

public static void main(String[] args) {
    // Create three threads
    Thread first = new TryThread(“first", “thread1", 200L);
    Thread second = new TryThread(“second", " thread2", 300L);
    Thread third = new TryThread(“third", " thread3", 500L);
   System.out.println("Press Enter when you have had enough...\n");
    first.start();                      // Start the first thread
    second.start();                     // Start the second thread
    third.start();                      // Start the third thread
try {
      System.in.read();                 // Wait until Enter key pressed
      System.out.println("Enter pressed...\n");
    } catch (IOException e) {           // Handle IO exception
      System.out.println(e);            // Output the exception
    }
    System.out.println("Ending main()");
    return;
  }

Daemon and user threads

A Daemon thread is simply a background thread that is subordinate to the thread that creates it. When the thread that created daemon ends the daemon thread also ends and dies with it. A thread is made daemon by the setDaemon() method. A thread that is not daemon is called a user thread. A user thread has a life of its own and it is not dependent of the thread that creates it

Threads by implementing Runnable interface

To implement Runnable interface, you’ll override the run() method.

class MyThread implements Runnable
{
  ...
  public void run()
  {
     // thread body of execution
  }
}

Creating Object:

MyThread myObject = new MyThread();

Creating Thread Object:

Thread thr1 = new Thread( myObject );

Start Execution:

thr1.start();

Why implement the Runnable interface

Extending the Thread class means that the subclass cannot extend any other class, whereas a class implementing the Runnable interface has this option. A class might only be interested in being runnable, and therefore, inheriting the full overhead of the Thread class would be excessive.

If a thread has been put to sleep, then the specified number of milliseconds must elapse (or it must be interrupted). If a thread has been suspended, then its resume() method must be invoked. If a thread is waiting on a condition variable, whatever object owns the variable must relinquish it by calling either notify() or notifyAll(). If a thread is blocked on I/O, then the I/O must complete.

A thread enters this state when the run() method has finished executing or when the stop() method is invoked. Once in this state, the thread cannot ever run again.

The Static sleep(milliseconds) Method

The sleep(long mills) method puts the thread to sleep for the specified time in milliseconds.

public void run() {
  for (int i = 1; i = 50) Thread.sleep(1);
    }
    catch (InterruptedException ex) {
    }
  }
}

Every time a number (>= 50) is printed, the thread is put to sleep for 1 millisecond.

Using isAlive() and join() method

The isAlive() method returns true if the thread upon which it is called is still running. The join() method waits until the thread on which it is called terminates. Its name comes from the concept of the calling thread waiting until the specified thread joins it. Additional forms of join allow you to specify a maximum amount of time that you want to wait for the specified thread to terminate.

Thread Priorities

Thread priorities are used by the thread scheduler to decide when each thread would be allowed to run. High priority thread gets more CPU time than low priority thread. A higher-priority thread can pre-empt a lower-priority thread. For example, when a low priority thread is running and a high priority thread resumes (from sleeping) it will pre-empt the low priority thread. To set thread priority use the setPriority(int level) method which is a member of thread. The value is within the range MIN_PRIORITY to MAX_PRIORITY, these values are 1 and 10 respectively. A level of 5 is default or NORM_PRIORITY

  • MIN_PRIORITY (1) Lowest Priority
  • NORM_PRIORITY (5) Default Priority
  • MAX_PRIORITY (10) Highest Priority

Priority Example

class Clicker implements Runnable{
	long   	      click=0;
	Thread   	      t;
	private boolean   running=true;

	public Clicker(int p){
		t=new Thread(this);
		t.setPriority(p);	}

	public void run(){
		while (running)
			click++;	}

	public void stop(){
		running=false;	}

	public void start(){
		t.start();	}
}
public class HiLo{
public static void main(String args[]){

	Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
	Clicker hi = new Clicker(Thread.NORM_PRIORITY+2);
	Clicker lo = new Clicker(Thread.NORM_PRIORITY-2);

	lo.start();
	hi.start();

	try{

	Thread.sleep(10000);
	}catch (InterruptedException ie){
		System.out.println("Main thread interrupted!");
	}

	lo.stop();
	hi.stop();
	System.out.println("lo thread"+lo.click);
                   System.out.println("hi thread"+hi.click);
}
}

The deprecated stop(), suspend(), and resume() Methods

NOTE: The Thread class also contains the stop(), suspend(), and resume() methods. As of Java 2, these methods are deprecated (or outdated) because they are known to be inherently unsafe. You should assign null to a Thread variable to indicate that it is stopped rather than use the stop() method.

Related Posts

Tagged with: JAVAJAVA GUIObject OrientedThreads
 

Comments are closed.

Looking for something?

Use the form below to search the site:


Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Related News Feeds