Why need Threads and how to use Threads in java

Why need threads?

see the demo as follow:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
public class Crawler_1 {
private static int i = 0;
public static void main(String[] args) throws InterruptedException {
long t0 = System.currentTimeMillis();
slowFileOperation();
slowFileOperation();
slowFileOperation();
slowFileOperation();
slowFileOperation();
long t1 = System.currentTimeMillis();
System.out.println("cost time:"+(t1-t0)+"ms");
}

private static void slowFileOperation() {
i += 1;
System.out.println("I is :" + i);
try{
File tmp= File.createTempFile("tmp","");
for (int i = 0;i<10000;i++){
try(FileOutputStream fos = new FileOutputStream(tmp)){
fos.write(i);
}
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}

when running this program,we can see that it costs about 6855ms;

Now see another demo:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;

public class Crawler_1 {
private static int i = 0;
public static void main(String[] args) throws InterruptedException {
long t0 = System.currentTimeMillis();
new Thread(Crawler_1::slowFileOperation).start();
new Thread(Crawler_1::slowFileOperation).start();
new Thread(Crawler_1::slowFileOperation).start();
new Thread(Crawler_1::slowFileOperation).start();
slowFileOperation();
long t1 = System.currentTimeMillis();
System.out.println("cost time:"+(t1-t0)+"ms");
}

private static void slowFileOperation() {
i += 1;
System.out.println("I is :" + i);
try{
File tmp= File.createTempFile("tmp","");
for (int i = 0;i<10000;i++){
try(FileOutputStream fos = new FileOutputStream(tmp)){
fos.write(i);
}
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}

It turns out that it costs about 3500ms;

Obviously, In this case, it is more efficient when using multiple threads;

How to crate a thread in java

There are two ways for creating a thread in Java: by extending the Thread class; and by implementing the Runnable interface. Both are in the java.lang package so you don’t have to use import statement.

Then you put the code that needs to be executed in a separate thread inside the run() method which is overridden from the Thread/Runnable. And invoke the start() method on a Thread object to put the thread into running status (alive).

The following class, ThreadExample1, demonstrates the first way:

public class Thread_4 {
static class ThreadExample1 extends Thread {

public void run() {
System.out.println("My name is: " + getName());
}

public static void main(String[] args) {
ThreadExample1 t1 = new ThreadExample1();
t1.start();
System.out.println("My name is: " + Thread.currentThread().getName());
}

}
}

You see that the ThreadExample1 class extends the Thread class and overrides the run() method. Inside the run() method, it simply prints a message that includes the name of the thread, which is returned from the getName() method of the Thread class.

And now let’s see the main() method that is invoked when the program starts. It creates an instance of the ThreadExample1 class and call its start() method to put the thread into running state. And the last line prints a message that includes the name of the main thread — every Java program is started from a thread called main. The static method currentThread() returns the Thread object associated with the current thread.

The output is as follows:

There are actually 2 threads:

  • Thread-0: is the name of the thread we created.
  • main: is the name of the main thread that starts the Java program.

The thread Thread-0 terminates as soon as its run() method runs to complete, and the thread main terminates after the main() method completes its execution.

One interesting point is that, if you run this program again for several times, you will see sometimes the thread Thread-0 runs first, sometimes the thread main runs first. This can be recognized by the order of thread names in the output changes randomly. That means there’s no guarantee of which thread runs first as they are both started concurrently. You should bear in mind this behavior with regard to multi-threading context.

Now, let’s see the second way that uses the Runnable interface. In the code below, the ThreadExample2 class implements the Runnable interface and override the run() method:

As you can see, there’s a small difference as compared to the previous program: An object of type Runnable (the ThreadExample2 class) is created and passed to the constructor of a Thread object (t2). The Runnable object can be viewed as a task which is separated from the thread that executes the task.

The two programs behave the same. So what are the pros and cons of these two ways of creating a thread?

The answer is here:

- Extending the Thread class can be used for simple cases. It cannot be used if your class needs to extend another class because Java doesn’t allow multiple inheritances of class.

- Implementing the Runnable interface is more flexible as Java allows a class can both extend another class and implement one or more interfaces.

--

--

--

Love podcasts or audiobooks? Learn on the go with our new app.

Why is important to have a healthy data architecture?

Hybrid and Multi-Cloud Perspectives: 2020 trends driving deliberate, strategic adoption

An Introduction to Inheritance in Python

Keeping Catalog Models Up-to-Date with Shopify Webhooks

LeetCode 122. Best Time to Buy and Sell Stock II

Shared Components Best Practices for 2019

Design Tokens in React and How We Use Them

Ajax Calls in Rails. How to implement Delete Actions Without Reloading the Page?

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
richard1230

richard1230

More from Medium

STATIC VS DYNAMIC LIBRARIES

Standardization of App Deployment

Stacey Matriks — Identify Your Software Project Complexity