With the development of computer from single core to multi-core, the program pursues parallel processing, and the real-time demand becomes better realized. Threading can make full use of the CPU processing capacity of contemporary multi-core processors, enhance the running efficiency of programs, and achieve the effect of multi-task parallel processing.

Threads in Java

There are four ways to create a thread in Java

  • Implement the Runnable interface
  • Thread class (implements the Runnable interface)
  • ThreadPool (ThreadPool execution)
  • Callable/Future (thread with return value, thread pool submit task) basic application

Thread

public class CallableDemo implements Callable<String> { @Override public String call() throws Exception { System.out.println("callable running"); return "Callable return"; } } public class RunnableDemo implements Runnable { @Override public void run() { System.out.println("Runnable running"); } } public class ThreadExtendDemo extends Thread{ @Override public void run() { System.out.println("Extend Thread running"); Public static void main(String[] args) {// RunnableDemo RunnableDemo = new RunnableDemo(); new Thread(runnableDemo).start(); ThreadRunning = new Thread(() -> system.out.println ("new Thread running")); threadRunning.start(); new ThreadExtendDemo().start(); // Number of core threads, maximum number of threads, lifetime of idle worker threads, unit of time, block queue for caching tasks, ThreadPoolExecutor ThreadPoolExecutor = new ThreadPoolExecutor(2, 4, 3, timeunit. SECONDS, new ArrayBlockingQueue<Runnable>(3), Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardOldestPolicy()); threadPoolExecutor.execute(() -> { System.out.println("Thread pool create thread running"); }); threadPoolExecutor.shutdown(); / / way four ExecutorService threadPool = Executors. NewSingleThreadExecutor (); Future<String> future = threadPool.submit(new CallableDemo()); try { System.out.println(future.get()); } catch (Exception e) { // ignore } finally { threadPool.shutdown(); }}}Copy the code

The results

Runnable running
new thread running
Extend Thread running
callable running
Callable return
Thread pool create thread runningCopy the code

The basis of concurrency

Thread state

You can see from the State enumeration in the Thread class that there are six states of a Thread

Public enum State {// create NEW, // run (including ready and running) RUNNABLE, // BLOCKED, // wait for, // wait for, // // end TERMINATED TIMED_WAITING with timeout (sleep(1000) TERMINATED; }Copy the code

We understand thread state transitions through flowcharts

Thread status Demo

public class ThreadStatusDemo { public static void main(String[] args) { new Thread(() -> { while (true) { try { TimeUnit.SECONDS.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }, "Time Waiting Thread").start(); new Thread(() -> { while (true) { synchronized (ThreadStatusDemo.class) { try { ThreadStatusDemo.class.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } }, "Waiting Thread").start(); new Thread(() -> { synchronized (ThreadStatusDemo.class) { while (true) { } } }, "Blocked Thread Holder").start(); new Thread(() -> { synchronized (ThreadStatusDemo.class) { while (true) { } } }, "Blocked Thread").start(); }}Copy the code

Using JPS to view the process, using jStack to view the thread running status can be seen

"Blocked Thread" #13 prio=5 os_prio=31 tid=0x00007fb44d05f000 nid=0x3e03 waiting for monitor entry [0x000070000dbc7000] java.lang.Thread.State: BLOCKED (on object monitor) at com.ognice.threaddemo.ThreadStatusDemo.lambda$main$3(ThreadStatusDemo.java:38) - waiting to lock <0x000000076ada7c58> (a java.lang.Class for com.ognice.threaddemo.ThreadStatusDemo) at com.ognice.threaddemo.ThreadStatusDemo? Lambda$4/1791741888.run(Unknown Source) at java.lang.Thread.run(Thread.java:748) "Blocked Thread Holder" #12 prio=5 os_prio=31 tid=0x00007fb44da27800 nid=0x3f03 runnable [0x000070000dac4000] java.lang.Thread.State: RUNNABLE at com.ognice.threaddemo.ThreadStatusDemo.lambda$main$2(ThreadStatusDemo.java:31) - locked <0x000000076ada7c58>  (a java.lang.Class for com.ognice.threaddemo.ThreadStatusDemo) at com.ognice.threaddemo.ThreadStatusDemo?Lambda$3/2065951873.run(Unknown Source) at java.lang.Thread.run(Thread.java:748) "Waiting Thread" #11 prio=5 os_prio=31 tid=0x00007fb44d05a000 nid=0x4103 in Object.wait() [0x000070000d9c1000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x000000076ada7c58> (a java.lang.Class  for com.ognice.threaddemo.ThreadStatusDemo) at java.lang.Object.wait(Object.java:502) at com.ognice.threaddemo.ThreadStatusDemo.lambda$main$1(ThreadStatusDemo.java:22) - locked <0x000000076ada7c58> (a java.lang.Class for com.ognice.threaddemo.ThreadStatusDemo) at com.ognice.threaddemo.ThreadStatusDemo?Lambda$2/363771819.run(Unknown Source) at java.lang.Thread.run(Thread.java:748) "Time Waiting Thread" #10 prio=5 os_prio=31 tid=0x00007fb44e0d8800 nid=0x3a03 waiting on condition [0x000070000d8be000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at java.lang.Thread.sleep(Thread.java:340) at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386) at com.ognice.threaddemo.ThreadStatusDemo.lambda$main$0(ThreadStatusDemo.java:12) at com.ognice.threaddemo.ThreadStatusDemo?Lambda$1/2129789493.run(Unknown Source) at java.lang.Thread.run(Thread.java:748)Copy the code

Only the observable states are shown here. The other states are basically converted directly. About Thread starting: We know that we can start a Thread with the thread.start () method. OS ::create_thread(this,thr_type,stack_sz); Call the operating system command to create a thread.

The termination of the Thread

The underlying JVM Thread holds the _interrupted flag (in the osThread. HPP file), which is used to determine the terminated status of a Thread. By calling the

Thread.interrupt (); thread.interrupt(); Thread.currentthread ().isinterrupted ();Copy the code

Native methods in Thread

// Check whether the current thread has stopped private native Boolean isInterrupted(Boolean ClearInterrupted);Copy the code

About InterruptedException

If interrupt() is called to terminate a thread while it is blocking (calling wait,sleep,join, etc.), the blocking thread attempts to terminate what it is doing and throws InterruptedException, but does not terminate the thread. You need to handle how to terminate the thread yourself. That is, the thread just receives a termination signal and throws an exception, but it doesn’t help you terminate the thread. It just tells you that the thread has terminated, and it’s up to you to decide what to do next. The thread can then be terminated in the exception handler or thrown to the outer handler. You can see in the code that if InterruptedException is triggered, the thread continues to execute if no processing is done.

public class ThreadInterruptedDemo { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(() -> { while (! Thread.currentThread().isInterrupted()) { try { TimeUnit.SECONDS.sleep(2); System.out.println("doing"); } catch (InterruptedException e) { e.printStackTrace(); / / by Thread. CurrentThread. Interrupt (); break; Equal terminating method terminates}}}); thread.start(); TimeUnit.SECONDS.sleep(1); thread.interrupt(); System.out.println(thread.isInterrupted()); }}Copy the code

Operation of the

false
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at java.lang.Thread.sleep(Thread.java:340)
    at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
    at com.ognice.threaddemo.ThreadInterruptedDemo.lambda$main$0(ThreadInterruptedDemo.java:10)
    at java.lang.Thread.run(Thread.java:748)
doing
doing
doing
doingCopy the code

About the Thread. Interrupted ()

Resetting the current thread termination state is a class method. This tells the outside world that the thread has terminated (the status flag is reset to false), but it is up to you to decide when to terminate the thread.

The difference between wait() and sleep(

  • Wait belongs to the object method, and sleep belongs to the Thread method
  • Wait releases locks, sleep does not
  • Wait must first get to lock or trigger IllegalMonitorStateException abnormalities, notify/notifyAll as also need to wake up

The join () and the yield ()

  • Join: Object method. Join is waiting for the thread’s execution method to complete and then continue to walk down, can be used to achieve orderly execution of the thread, need to catch InnterruptedException
  • Yield: Static method of Thread class. The yield effect is to convert a thread to a ready state, causing the CPU to reschedule the thread. A thread with a higher priority than the current thread can be given the opportunity to execute.