This series of posts is a summary of the concurrent chapters in core Java Technologies, a really good book with comprehensive knowledge and good translation.

What is a thread

Thread is the smallest unit of operation scheduling that an operating system can do. It is contained in a process and is the actual operating unit of a process. That is, a thread is a vehicle for code to run. We write code that runs on a thread. Take the simplest hellowWorld example:

public class Main {

    public static void main(String[] args) {
        System.out.println("Hello World!");
        System.out.println("Current thread name:"+Thread.currentThread().getName());
        System.out.println("Current thread ID is:"+Thread.currentThread().getId()); }}Copy the code

The result is:

Hello World! The current thread name is main. The current thread ID is 1Copy the code

By default, a main thread is created to execute code while the program is running. The thread name is main and the thread ID is 1

What is multithreading

As the name implies, multiple threads run at the same time to improve the execution speed of the program. A single thread can only do one thing at a time, and there are two ways to improve execution efficiency:

  • Asynchronous. Because most of the time threads are not doing calculations all the time, they are waiting for IO operations, so you can use that waiting time to improve thread utilization. We won’t go into too much detail here, but if you want to learn more about asynchrony, you can learn Node.js(native support for asynchrony).
  • Multithreading. Since one thread can only do one thing at a time, multiple threads can do multiple things at the same time, increasing the number of threads to speed up execution.

How to create a thread

There are two ways to create a thread

  • Thread class inheritance
  • Implement the Runnable interface

Thread class inheritance

This method is not recommended for Thread creation for obvious reasons: Java does not support multiple inheritance, and if you inherit from Thread, you cannot inherit from other classes.

Create thread code using inheritance as follows:

public class CustomThreadExtendThread extends Thread{

    @Override
    public void run(a) {
        String threadName = Thread.currentThread().getName();
        long threadId = Thread.currentThread().getId();
        System.out.println("Create thread name:"+threadName+", id is:"+threadId);
    }

    public static void main(String[] args){
        Thread thread1 = new CustomThreadExtendThread();
        Thread thread2 = newCustomThreadExtendThread(); thread1.start(); thread2.start(); }}Copy the code

Implement the Runnable interface

Implementing interfaces to create threads is currently recommended for a simple reason: one class can implement multiple interfaces. Implementing the Runnable interface does not affect the implementation class’s ability to implement other interfaces.

Create thread code using the implementation interface as follows:

public class CustomThreadImplementInterface implements Runnable {
    @Override
    public void run(a) {
        Thread.currentThread().setName(((Double) Math.random()).toString());
        String threadName = Thread.currentThread().getName();
        long threadId = Thread.currentThread().getId();
        System.out.println("Create thread name:" + threadName + ", id is:" + threadId);
    }

    public static void main(String[] args) {
        Thread thread1 = new Thread(new CustomThreadImplementInterface());
        Thread thread2 = new Thread(new CustomThreadExtendThread());
        thread1.start();
        thread2.start();

        // Use lambda expressions to make thread creation easier
        new Thread(() -> {
            System.out.println("Created a new thread"); }).start(); }}Copy the code

The Thread class is also an implementation of the Runnable interface.

PS: The subsequent code all uses runnable to create threads

Thread state

The thread creation was just demonstrated above, now let’s look at the thread state in detail. In the Java specification, threads can have the following six states:

  • New(New created)
  • Runnable
  • Blocked (block)
  • Waiting (wait)
  • Timed waiting
  • Terminated

Newly created thread

When a Thread is created using the new operator, such as new Thread(r), it is created before it has even started running.

Runnable thread

Once the start method of the Thread class is called, the Thread is runnable.

Why is it runnable?

Because the Java specification does not define running on the CPU as a separate state. So a runnable thread may or may not be running, depending on the CPU’s scheduling policy.

Blocked threads and waiting threads

When a thread is in a blocked or waiting state, no code is running and the least resources are consumed. Until it runs again. There are several ways to put a thread into a blocked or wait state:

  • When a thread attempts to acquire an internal object lock that is held by another thread
  • A thread enters the wait state while waiting for another thread to notify the scheduler of a condition. Such as when calling object. wait or Thread.join methods, or waiting for Lock or Condition in the java.util.Concurrent library.
  • When the timing wait method is called. Such as Thread. Sleep, Object. Wait, Thread. Join, Lock. TryLock and Condition. Await

The terminated thread

A thread can enter the terminated state in one of two ways:

  • The run method ends and dies a natural death
  • An unexpected death occurred when the run method was aborted without catching

Note: The stop method that calls a thread can also terminate a thread, but this method has been deprecated and is best not used.

Thread attributes

Threads have various attributes: priority, daemons, thread groups, and handlers that handle uncaught exceptions.

Thread priority

In Java, each thread has a priority. By default, threads inherit the parent thread priority. You can also call the setPriority method to specify the priority. Priorities range from 1(MIN_PRIORITY) to 10(MAX_PRIORITY).NORM_PRIORITY is 5. These constants are defined in the Thread class.

Note: Thread priorities are highly system dependent, so when Java thread priorities are mapped to host platform priorities, the number of priorities may decrease or become zero. For example, if there are seven priorities in Windows, some of the priorities will map to the same operating system priorities when Java threads are mapped. In the Java virtual machine written by Oracle for Linux, thread priority is ignored; all Java threads have the same priority. Don’t write code that relies on priorities.

Daemon thread

Convert a Thread to a daemon Thread by calling Thread.setdaemon (true). The only user of a daemon thread is to provide services to other threads, such as timing threads, which periodically send timing signals to other threads. Therefore, when only daemons are present in the virtual machine, the virtual machine shuts down and exits. Do not access any resources or process any business logic in the daemon thread

No exception handler was caught

A thread’s run method cannot throw any checked exceptions. Unchecked exceptions cause the thread to terminate. Exceptions can be handled by uncaught handlers in addition to try/catch. The exception handler needs to implement Thread. UncaughtExceptionHandler interface.

Can use Thread sample setUncaughtExceptionHandler () method for a Thread processor, also can use the small setDefaultUncaughtExceptionHandler () for all threads to set the default processor, the code is as follows:

public class CustomExceptionHandler implements Thread.UncaughtExceptionHandler {

    @Override
    public void uncaughtException(Thread t, Throwable e) {
        System.out.println("Thread caught"+t.getName()+", exception: + e.getMessage());
        e.printStackTrace();
    }

    public static void main(String[] args) {
        Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler());
        new Thread(() -> {
            throw new RuntimeException("test"); }).start(); }}Copy the code

If you do not set the default processor and do not set the processor for a separate Thread, then the Thread processor for the Thread’s Thread group objects — ThreadGroup (because the Thread group has realized the Thread object. UncaughtExceptionHandler interface).

All the code used in this article: Github

This article was originally published at: [www.tapme.to]