Appearance
Creating New Threads
Java language has built-in support for multithreading. When a Java program starts, it actually launches a JVM process, and the JVM starts the main thread to execute the main()
method. Within the main()
method, we can start additional threads.
Creating a New Thread
Creating a new thread is very straightforward. We need to instantiate a Thread
object and then call its start()
method:
java
// Multithreading
public class Main {
public static void main(String[] args) {
Thread t = new Thread();
t.start(); // Start a new thread
}
}
However, this thread will do nothing and terminate immediately after starting. We want the new thread to execute specific code. There are several ways to achieve this:
Method 1: Extend the Thread
Class and Override the run()
Method
java
// Multithreading
public class Main {
public static void main(String[] args) {
Thread t = new MyThread();
t.start(); // Start a new thread
}
}
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Start new thread!");
}
}
When executing the above code, note that the start()
method internally calls the instance’s run()
method automatically.
Method 2: Pass a Runnable
Instance When Creating the Thread
java
// Multithreading
public class Main {
public static void main(String[] args) {
Thread t = new Thread(new MyRunnable());
t.start(); // Start a new thread
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Start new thread!");
}
}
Or, using the lambda syntax introduced in Java 8 for further simplification:
java
// Multithreading
public class Main {
public static void main(String[] args) {
Thread t = new Thread(() -> {
System.out.println("Start new thread!");
});
t.start(); // Start a new thread
}
}
Question: Does using a thread to execute a print statement differ from executing it directly in the main()
method?
Answer: Yes, there is a significant difference. Consider the following code:
java
public class Main {
public static void main(String[] args) {
System.out.println("Main start...");
Thread t = new Thread() {
public void run() {
System.out.println("Thread run...");
System.out.println("Thread end.");
}
};
t.start();
System.out.println("Main end...");
}
}
Here, the main thread (indicated in blue) executes four lines of code:
- Prints "Main start..."
- Creates a
Thread
object - Calls
start()
to launch the new thread - Prints "Main end..."
When the start()
method is called, the JVM creates a new thread represented by the instance t
and begins its execution concurrently. Meanwhile, the main thread continues to execute and prints "Main end...". The new thread t
concurrently executes and prints "Thread run..." and "Thread end."
When the run()
method completes, the new thread terminates. Similarly, when the main()
method finishes, the main thread terminates.
Execution Order of Threads
Consider the following execution sequence:
- The main thread always prints "Main start..." first.
- It then prints "Main end..." but the order between "Main end..." and the thread's "Thread run..." and "Thread end." messages is not guaranteed. This is because once the new thread starts running, both the main thread and the new thread execute concurrently, and their exact scheduling is determined by the operating system.
Simulating Concurrent Execution with Thread.sleep()
To simulate the effect of concurrent execution, we can use Thread.sleep()
within the threads to force them to pause for a certain period:
java
// Multithreading
public class Main {
public static void main(String[] args) {
System.out.println("Main start...");
Thread t = new Thread() {
public void run() {
System.out.println("Thread run...");
try {
Thread.sleep(10);
} catch (InterruptedException e) {}
System.out.println("Thread end.");
}
};
t.start();
try {
Thread.sleep(20);
} catch (InterruptedException e) {}
System.out.println("Main end...");
}
}
The sleep()
method takes a parameter in milliseconds. By adjusting the sleep duration, we can observe different execution orders between the main thread and the new thread.
Important Note: Directly calling the run()
method of a Thread
instance is ineffective:
java
public class Main {
public static void main(String[] args) {
Thread t = new MyThread();
t.run();
}
}
class MyThread extends Thread {
public void run() {
System.out.println("Hello");
}
}
Calling the run()
method directly is equivalent to invoking a regular Java method. The current thread (main thread) remains unchanged, and no new thread is created. The above code simply calls the run()
method within the main()
thread, printing "Hello" without creating any new threads.
Must Call start()
: To actually start a new thread, you must call the start()
method on the Thread
instance. If you examine the Thread
class source code, you'll find that the start()
method internally invokes a private native method start0()
. The native
modifier indicates that this method is implemented in the JVM’s internal C code, not in Java.
Thread Priority
Threads can be assigned priorities using the following method:
java
Thread.setPriority(int n) // 1~10, default value is 5
The JVM automatically maps priorities from 1 (low) to 10 (high) to the actual operating system priorities (different operating systems have varying priority ranges). Higher-priority threads are scheduled more frequently by the operating system, but you cannot rely on priority settings to ensure that high-priority threads will always execute first.
Exercise
Create a new thread.
Summary
- Thread Representation: Java uses
Thread
objects to represent threads. Callingstart()
on aThread
instance launches a new thread. - Single
start()
Call: A thread object can only have itsstart()
method called once. - Execution Code: The code executed by a thread is written inside the
run()
method. - Thread Scheduling: Thread scheduling is determined by the operating system, and the program itself cannot dictate the scheduling order.
- Pausing Threads:
Thread.sleep()
can pause the current thread for a specified duration.