Showing posts with label thread. Show all posts
Showing posts with label thread. Show all posts

Sunday, 29 March 2020

Thread.start() vs Runnable.run()

Difference 1: Thread.start() execute the run() method in separate thread.

Thread start() method create new thread, which will call the run method internally. But when you execute 'run()' method of Runnable object directly, then it execute by the same thread that invokes run() method.

Example
Runnable runnable1 = .....;
Runnable runnable2 = .....;

When you call run method of Runnables runnable1, runnable2 directly from the main method, then these methods get executed by main thread.

App.java
package com.sample.app;

public class App {

	public static void main(String args[]) {
		Runnable runnable1 = () -> {
			Thread currentThread = Thread.currentThread();

			System.out.println("Runnable 1 is executed by : " + currentThread.getName());
		};

		Runnable runnable2 = () -> {
			Thread currentThread = Thread.currentThread();

			System.out.println("Runnable 2 is executed by : " + currentThread.getName());
		};

		runnable1.run();
		runnable2.run();

	}

}

Output
Runnable 1 is executed by : main
Runnable 2 is executed by : main

Passing Runnables to a thread
Thread thread1 = new Thread(runnable1);
Thread thread2 = new Thread(runnable2);

When you call thread1.start(), it starts a new thread and calls the run() method of runnable runnable1 within the new thread.

App.java
package com.sample.app;

public class App {

	public static void main(String args[]) {
		Runnable runnable1 = () -> {
			Thread currentThread = Thread.currentThread();

			System.out.println("Runnable 1 is executed by : " + currentThread.getName());
		};

		Runnable runnable2 = () -> {
			Thread currentThread = Thread.currentThread();

			System.out.println("Runnable 2 is executed by : " + currentThread.getName());
		};

		Thread thread1 = new Thread(runnable1);
		Thread thread2 = new Thread(runnable2);

		thread1.start();
		thread2.start();

	}

}

Output
Runnable 1 is executed by : Thread-0
Runnable 2 is executed by : Thread-1

Difference 2: run() method can be called any number of times, but start() method can be called atmost once.

If you call start() method of already started thread, then IllegalThreadStateException is thrown.

App.java
package com.sample.app;

public class App {

	public static void main(String args[]) {
		Runnable runnable1 = () -> {
			Thread currentThread = Thread.currentThread();

			System.out.println("Runnable 1 is executed by : " + currentThread.getName());
		};

		runnable1.run();
		runnable1.run();

		Thread thread1 = new Thread(runnable1);

		thread1.start();
		thread1.start();

	}

}

Output
Runnable 1 is executed by : main
Runnable 1 is executed by : main
Runnable 1 is executed by : Thread-0
Exception in thread "main" java.lang.IllegalThreadStateException
	at java.lang.Thread.start(Thread.java:708)
	at com.sample.app.App.main(App.java:18)

Difference 3: Most of the code of Thread start() method written in native language.

When you see the definition of start() method of Thread class, it looks like below.
public synchronized void start() {
		if (threadStatus != 0)
			throw new IllegalThreadStateException();

		group.add(this);

		boolean started = false;
		try {
			start0();
			started = true;
		} finally {
			try {
				if (!started) {
					group.threadStartFailed(this);
				}
			} catch (Throwable ignore) {

			}
		}
}

private native void start0();

As you see above definition, actual logic of thread starting (start0()) method is written in native language. Whereas definition of run method will be written in pure Java.


You may like

Sunday, 12 January 2020

How to specify timeout to a thread?


There can be multiple ways to stop a thread after certain time period. I choose below approach.

Just interrupt the thread, when thread reaches to specified time.


Step 1: Create TimerTask that interrupts the thread after given time.

TimeoutTask.java
package com.sample.app;

import java.util.TimerTask;

public class TimeoutTask extends TimerTask {
 Thread thread;

 TimeoutTask(Thread thread) {
  this.thread = thread;
 }

 public void run() {
  if (thread != null && thread.isAlive()) {
   thread.interrupt();
  }
 }

}

Step 2: Create runnable task that schedules the timer task before starting execution.


MyTask.java
package com.sample.app;

import java.util.Timer;
import java.util.concurrent.TimeUnit;

public class MyTask implements Runnable {
 private long timeoutInSeconds;
 Timer timer;

 MyTask(long timeoutInSeconds) {
  this.timeoutInSeconds = timeoutInSeconds;
  timer = new Timer(true);
 }

 @Override
 public void run() {
  timer.schedule(new TimeoutTask(Thread.currentThread()), timeoutInSeconds * 1000);
  int count = 0;
  while (true) {
   count++;
   try {
    TimeUnit.SECONDS.sleep(1);
    System.out.println("Executed for " + count + " seconds");
   } catch (InterruptedException e) {
    System.out.println("Task interrupted");
    break;
   }
  }
 }

}


App.java
package com.sample.app;

public class App {

 public static void main(String args[]) {
  // Set the time out for task
  MyTask task = new MyTask(5);
  Thread thread = new Thread(task);

  thread.start();

 }

}


Run App.java, you will see below messages in console.
Executed for 1 seconds
Executed for 2 seconds
Executed for 3 seconds
Executed for 4 seconds
Task interrupted


You may like