This is the 14th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Multithreading today, if you’re a little confused about processes and threads, you can move on to processes and threads.

To achieve multithreading, we must first learn to create threads. There are three ways to create a thread.

1 Inherits Thread. Declare a subclass of Thread that overrides the run method of Thread. The thread can then be started using the start method.

public class Thread1 extends Thread{ private String name; public Thread1(String name) { this.name = name; } @Override public void run() { for(int i = 0; i < 5; i++){ System.out.println(name +"-----"+ i ); try { sleep(1000); // Do not sleep, just to demonstrate the effect of thread switching. } catch (InterruptedException e) { e.printStackTrace(); }} public static void main(String[] args) {Thread1 t1 = new Thread1("1 "); Thread1 t2 = new Thread1("2 "); t1.start(); t2.start(); }}Copy the code

2 Implement the Runnable interface. Declare a subclass that implements the Runnable interface and overrides the run method.

public class TaskNoResult implements Runnable{ private String name; public TaskNoResult(String name) { this.name = name; } @Override public void run() { for(int i = 0; i < 5; i++){ System.out.println(name +"-----"+ i ); try { Thread.sleep(1000); // Do not sleep, just to demonstrate the effect of thread switching. } catch (InterruptedException e) { e.printStackTrace(); }} public static void main(String[] args) {new Thread(new TaskNoResult(" TaskNoResult ").start(); New Thread(new TaskNoResult(" task 2")).start(); }}Copy the code

In essence, Thread inheritance is also implementing the Runnable interface. The only way to start threads is through the start method of Thread class, which is a native method to execute the run method. The contents of the run method are simply the execution body of the thread. Remember, there is only one way to start a Thread, and that is through the Start method of the Thread class.

The advantages of implementing the Runnable interface are as follows:

  1. Avoid the limitations of single inheritance

  2. Threaded code can be shared by multiple threads

  3. Suitable for multiple threads working on the same resource

  4. When using thread pools, only Runnable or Callable threads can be placed.

3 Implement the Callable interface. The Callable interface was introduced in JDK1.5, and we can create threads by implementing it and overriding the Call method.

public class TaskWithResult implements Callable<String>{ private int id; public TaskWithResult(int id) { this.id = id; } @override public String call() throws Exception {return id+" The task is executed by a thread driver!" ; } -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- test as follows -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the public static void main (String [] args) throws InterruptedException, ExecutionException {/ / use the Executors create a thread pool to perform a task the ExecutorService pool = Executors. NewCachedThreadPool (); ArrayList<Future<String>> Results = new ArrayList<Future<String>>(); for (int i = 0; i < 10; i++) { results.add(pool.submit(new TaskWithResult(i))); } for (Future<String> fs : results) { if (fs.isDone()) { System.out.println(fs.get()); } else {system.out. println("Future result is not yet complete"); } } pool.shutdown(); }}Copy the code

Runnable and Callable:

  1. Runnable overrides the run method, while Callable overrides the call method.

  2. Runnable has no return value, Callable has a return value.

  3. The run method cannot throw an exception. The call method can.

  4. To get a Future object, run the Callable task.

public interface Future<V> { boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); V get() throws InterruptedException, ExecutionException; V get(long timeout, TimeUnit Unit) throws InterruptedException, ExecutionException, TimeoutException; }Copy the code

The Future is an interface that gives us methods to detect whether the current task has finished, and to wait for the task to finish and get a result. By calling the Future’s get method, we can return a result value when the task is finished. If the work is not finished, the current thread will be blocked until the task is finished. We can stop a task by calling the Cancel method, which will return true if the task has stopped. Cancel returns false if the task is completed or stopped or the task cannot be stopped. When a task is successfully stopped, it cannot be performed again. The isDone and isCancel methods determine whether the current work is complete and canceled.

Both Runnable and Callable are used to create a task, and we use threads to drive the execution of the task. The general approach is something like this:

New Thread(new TaskNoResult(" task 1")).start(); New Thread(new TaskNoResult(" task 2")).start();Copy the code

However, it is not recommended to use thread pools to create threads and drive task execution. Like this:

ExecutorService pool = Executors.newCachedThreadPool(); Pool. execute(new TaskNoResult(" task 1")); Pool. execute(new TaskNoResult(" task 2"));Copy the code

Here’s a thread life cycle diagram that’s worth looking at.

A few words about methods in threads.

Start () : A method to start a thread, but there is no guarantee that it will execute immediately.

Sleep (long) : Suspends the thread for a period of time in milliseconds.

Join () : joins the specified thread to the current thread and waits for it to complete. It can be used to control the thread execution order.

Yield () : a thread yields CPU to a thread of the same priority, but success is not guaranteed.

Finally, a practical tip that is not recommended is to set thread priorities. Because priority is not a determinant of the order in which threads are executed, you should never expect to set priorities to control the order in which threads are executed.

t.setPriority(Thread.MIN_PRIORITY); // Minimum 1 t.setPriority(thread.norm_priority); // Default value 5 t.setPriority(thread.max_priority); / / top 10Copy the code