This is the 10th day of my participation in the August More Text Challenge

An overview of the

In our running system, we run more threads. For example, when we run a Jvm, the operating system creates a Jvm process to run our Java application. However, the smallest unit of scheduling in modern operating systems is threads, so we can create multiple threads in a running Jvm process. These threads have their respective program counter, stack and a local variable attributes, such as access to Shared memory variable, because multiple threads can access the Shared memory variable, so at the time of multithreaded programming, we more is the safety of the thread, through a series of measures to ensure the accuracy of the Shared memory data. The processor runs different threads by switching time slices at high speed, giving the impression that multiple threads are running at the same time. In Java applications, the entry point for Java is the Main() method. Many people believe that there is no multi-threaded code logic in the code, so a Jvm only runs one thread

// Get the Java thread management MxBean
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
// Get thread related information
ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false.false);
for (ThreadInfo threadInfo : threadInfos) {
    System.out.println(threadInfo.getThreadId() + "." + threadInfo.getThreadName());
}
Copy the code

Running results:

6.Monitor Ctrl-Break		  //Idea specific threads: monitor Ctrl+Brean key
5.Attach Listener             //Jvm interprocess communication listener
4.Signal Dispatcher           // Distribute threads that process signals sent to the JVM
3.Finalizer                   // The thread that calls the object Finalizer method
2.Reference Handler			  / / remove the Reference
1.main                        //main thread, program entry
Copy the code

As can be seen from the printed results above, we start a main method, which actually has 6 threads running. Normally, we only focus on the code logic in main, but we do not care about the logic of other threads, so we generally do not contact the relevant logic of other threads.

The relevant knowledge

Create a thread

When creating a thread, there are three ways to create a thread

  • Thread class inheritance
  • Implement the Runable interface
  • Implement Callable interface

Thread state

  • NEW: Initial state where the thread has just been created and the start method has not been called
Thread thread = new Thread();
Copy the code
  • RUNNABLE: A RUNNING state in which the thread can execute when the run method is called. At this point, the thread can be divided into two conditions: RUNNING- the thread is RUNNING, and ready-waiting for the operating system to schedule the thread
thread.start();
Copy the code
  • BLOCKED: a state in which a thread runs without capturing the lock and is BLOCKED by the lock
  • WAITING: a state in which the current thread is WAITING for another thread to do something specific (notification or interrupt)
  • TIMED WAITING: a WAITING state, which is the same as WAITING, but has the difference that the TIMED state returns automatically after a certain period of time
  • TERMINATED: indicates that the current thread is TERMINATED

From the above Java thread state transition diagram, we can clearly understand what methods are used to switch to different states between each state. When entering the blocking state, it is the state when the thread is blocked in the synchronized keyword modified method or code block. Synchronized also corresponds to the Lock interface corresponding to the Lock, corresponding to the Lock into the state, the thread is waiting state, because the Lock interface for blocking implementation use LockSupport class related methods.

Daemon thread

Daemon threads are daemons. When the Java VIRTUAL machine exits, the thread mode does not block subsequent operations and exits automatically when the main thread is finished. Setting a Thread as a daemon is done by calling thread.setdaemon (true), which is set before calling start.

Thread priority

Sometimes, when the thread we created needs to be processed first, the operating system dispatcher will allocate the thread to several time slices, and when the thread runs out of time slices, it will switch to the scheduling of other threads, so we expect the operating system to call the processing first in the next allocation. Thread.setpriority (int) specifies the priority of a Thread. The value ranges from 0 to 10.

Thread the interrupt

A thread interrupt is an identifying bit property of a thread that indicates whether a running thread has been interrupted by another thread. A Thread checks whether it has been interrupted by using isInterrupted, or by using Thread.interrupted to restore the interrupt flag of the current Thread.

Termination of the thread

When we run a thread, we need to terminate the thread safely when certain conditions are reached. We can use thread interrupt techniques, or we can use thread shared variables to terminate the thread

public class ThreadDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new Runner());
        t1.start();
        TimeUnit.SECONDS.sleep(1);
        t1.interrupt();

        Runner r2 = new Runner();
        Thread t2 = new Thread(r2);
        t2.start();
        TimeUnit.SECONDS.sleep(1);
        r2.cancel();
    }

    public static class Runner implements Runnable {
        private volatile boolean on = true;

        private long i;

        @Override
        public void run(a) {
            while(on && ! Thread.currentThread().isInterrupted()) { i++; } System.out.println("i=" + i);
        }
        public void cancel(a) {
            on = false; }}}Copy the code

The code above uses two ways to terminate a thread that is currently running. This way, by identifying bits or interrupting operations, the thread can clean up resources when it terminates, rather than stopping the thread immediately, which makes it safer and more elegant to terminate the thread.

In programming, we tend to use threads individually less often, and mostly in combination with thread pools.