[chapter 06 multithreading] the highlight of Java language

❀ Write in front
❀ Blog home page: Hard working Naruto
❀ Series column: Java basic learning πŸ˜‹
❀ Welcome, friends, praise πŸ‘ follow πŸ”Ž Collection πŸ” Learning together!
❀ If there are mistakes, please correct them! 🌹

πŸ”₯ Series portal:
[chapter 05 Java exception handling] a short article teaches you to play with Java exception handling [hot list]
[appendix 2Java object-oriented programming] detailed explanation of inventory keywords this, super and final [hot list]
[chapter 04 Java object-oriented programming (Part 2)] the killer technology of object-oriented programming [hot list]
[chapter 04 Java object-oriented programming (middle)] decrypt inheritance and polymorphism [hot list]
[chapter 04 Java object-oriented programming (Part I)] the first experience of everything being an object [second in the hot list of the whole station]
[Appendix 1 common algorithms in Java arrays] the ten sorting algorithms are illustrated and explained in detail, giving you endless aftertaste
[chapter 03 Java arrays] programmers must see the detailed explanation of arrays
[chapter 02 basic Java syntax] the detailed explanation enables you to re understand the basic Java syntax and process control
[chapter 01 overview of Java language] Java has been studied for a long time. Come back and get familiar with it (detailed)

1, Basic concepts

πŸ”₯ program

Definition: a set of instructions written in a language to complete a specific task. It refers to a piece of static code, static object

πŸ”₯ process

Definition: it is an execution process of a program or a running program;
The process of its emergence, existence and extinction is the life cycle

πŸ”₯ thread

  1. Definition: a process can be further refined into a thread, which is an execution path within a program
  2. As the unit of scheduling and execution, each thread has its own running stack and program counter
  3. Multiple threads in a process share the same memory unit / memory address space. They allocate objects from the same heap and can access the same variables and objects

🎁 Note: if a process executes multiple threads in parallel at the same time, it supports multithreading

πŸ”₯ Parallelism and concurrency

● parallel: multiple CPU s execute multiple tasks at the same time, for example, multiple people do different things at the same time.
● Concurrency: a CPU executes multiple tasks at the same time, for example, multiple people do the same thing

2, Creation and use of threads

The JVM of the Java language allows programs to run multiple threads through Java Lang. thread class

πŸ”₯ Method 1: inherit Thread class

  1. Defines subclasses that inherit the Thread class
  2. Override the run method in the Thread class in the subclass
  3. Create a Thread subclass object, that is, create a Thread object
  4. Call the thread object start method: start the thread and call the run method
    Test ox knife:
class MyThread extends Thread{
	public MyThread(){
	super();
	}
	public void run(){
		for(int i = 0;i<100;i++){
			System.out.println("Child thread:" + i);
		}
	}
}
public class TestThread{
	public static void main(String[] args){
		//1. Create thread
		MyThread m = new MyThread();
		//2. Start the thread and call the run () method of the current thread
		m.start;
	}
}

πŸ”₯ Method 2: implement Runnable interface

  1. Define subclasses to implement the Runnable interface
  2. Override the run method in the Runnable interface in the subclass
  3. Create a Thread object through the Thread class argument constructor
  4. Pass the subclass object of Runnable interface as the actual parameter to the constructor of Thread class
    5) Call the start method of Thread class: start the Thread and call the run method of Runnable subclass interface
    Test ox knife:
//1. Create a class that implements the runnable interface
class MThread implements Runnable{
//2. Implement the class to implement the abstract method in runnable: run()
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if (i % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
    }
}

public class ThreadTest {
    public static void main(String[] args) {
        //3. Create an object that implements the class
        MThread mThread = new MThread();
        //4. Pass this object as a parameter to the constructor of Thread class and create the object of Thread class
        Thread t1 = new Thread(mThread);
        t1.setName("Thread one");
        //5.  Call start() through the object of Thread class: β‘  start the Thread β‘‘ call the run() of the current Thread
        t1.start();

        //Start another thread and traverse the even number within 100
        Thread t2 = new Thread(mThread);
        t2.setName("Thread two");
        t2.start();
    }
}

🎁 Note: to start multithreading, you must call the start method

πŸ”₯ JDK5.0 new thread creation method

πŸ‘Œ Method 3: implement Callable interface

Callable is more powerful than Runnable
Compared with the run() method, it can have return values, throw exceptions, support generic return values, and need to use the FutureTask class, such as obtaining the return results

  1. Steps:
  • Create a callable implementation class
  • Implement the call method and declare the operations to be performed by the secondary thread in call()
  • Create an object of the Callable interface implementation class
  • Pass the object of this Callable interface implementation class to the FutureTast constructor as an object to create FutureTast
  • Pass the FutureTast object as a parameter to the constructor of the Thread class, create the Thread object, and start()
  1. Upper Code:
//1. Create a callable implementation class
class NumThread implements Callable {
    //2. Implement the call method and declare the operating system fee to be executed by the secondary thread in call()
    @Override
    public Object call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
            if (i%2==0){
                System.out.println(i);
                sum += i;
            }

        }
        return sum;
    }
}
public class ThreadNew {
    public static void main(String[] args) {
        //3. Create an object of the Callable interface implementation class
        NumThread numThread = new NumThread();
        //4. Pass the object of this Callable interface implementation class to the FutureTast constructor as a and create the object of FutureTast
        FutureTask futureTask = new FutureTask(numThread);
        //5. Pass the FutureTast object as a parameter to the constructor of the Thread class, create the Thread object, and start()
        new Thread(futureTask).start();

        try {
            //The return value of get() is the return value of call() overridden by the FutureTest constructor parameter Callable implementation class
            Object sum = futureTask.get();
            System.out.println(sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

πŸ‘Œ Mode 4: use thread pool

  1. Idea: create multiple threads in advance, put them into the thread pool, obtain them directly during use, and put them back into the pool after use, so as to avoid frequent creation, destruction and reuse
  2. Steps:
  • Provides a thread pool for the specified number of threads
  • To execute the specified thread operation, you need to provide an object that implements the Runnable or Callable interface implementation class
  • Close thread pool
  1. Upper Code:
class NumberThread implements Runnable{
    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            if (i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
    }
}
class NumberThread1 implements Runnable{

    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            if (i % 2 != 0){
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
    }
}
public class ThreadPool {
    public static void main(String[] args) {
        //1. Provide a thread pool with a specified number of threads
        //ExecutorService is the interface, and service is the object of its implementation class
        ExecutorService service = Executors.newFixedThreadPool(10);

        ThreadPoolExecutor service1 = (ThreadPoolExecutor)service;
        //Set thread pool properties
//        System.out.println(service.getClass()); Find the implementation class of ExecutorService
//        service1.setCorePoolSize(15);// Core pool size
//        service1.setKeepAliveTime();// How long does the thread last when there is no task
//        service1.setMaximumPoolSize(100);// Maximum number of threads

        //2. To execute the specified thread operation, you need to provide an object that implements the Runnable or Callable interface implementation class
        service.execute(new NumberThread());//For Runnable
        service.execute(new NumberThread1());//For Runnable
//        service.submit(Callable callable);// For callable

        //3. Close thread pool
        service.shutdown();
    }
}

3, Thread life cycle

A complete life cycle usually experiences the following five states: new, ready, running, blocking and death
The knowledge points are shown in the figure:

Analyze the in the figure:
Operation of releasing lock
● synchronization method of current thread and execution end of synchronization code block
● the current thread encounters a break and return in the synchronization code block and synchronization method, which terminates the code block and the method
● the current thread has an unhandled Error or Exception in the synchronization code block and synchronization method, resulting in an abnormal end
● the current thread executes the wait() method of the thread object in the synchronization code block and synchronization method. The current thread pauses and releases the lock
Operation that does not release the lock
● when a thread executes a synchronous code block or synchronous method, the program calls thread sleep(),Thread. The yield () method pauses the execution of the current thread
● when a thread executes a synchronous code block, other threads call the suspend() method of the thread to suspend the thread, and the thread will not release the lock

4, Thread synchronization

Java provides a professional solution to the security problem of multithreading: synchronization mechanism

πŸ”₯Synchronized

  1. Sync code block:
    synchronized (object){
    //Code to be synchronized;
    }
  2. Synchronized can also be placed in a method declaration to indicate that the entire method is a synchronized method.
    For example:
    public synchronized void show (String name){
    ....
    }

πŸ”₯ lock

  1. Definition: synchronization is achieved by explicitly defining the synchronization Lock object. Using Lock objects as
    java.util.concurrent.locks.Lock interface is a tool that controls multiple threads to access shared resources
class A{
		private final ReentrantLock lock = new ReenTrantLock();
		public void m(){
		lock.lock();
		try{
			//Thread safe code;
		}
		finally{
				lock.unlock();
		}
	}
}
  1. What is a synchronized lock?
    ● any object can be used as a synchronization lock. All objects automatically contain a single lock (monitor).
    ● lock of synchronous method: static method (class name). Class), non static method (this)
    ● synchronous code block: it is specified by itself, and often it is also specified as this or class name class

It is also analyzed in the analysis under the thread life cycle diagram

πŸ‘Œ deadlock

Different threads occupy the synchronization resources needed by the other party and do not give up. They are waiting for the other party to give up the synchronization resources they need, forming a thread deadlock. After the deadlock occurs, there will be no exception and no prompt, but all threads are blocked and cannot continue

The code is as follows:

public class DeadLockTest {
		public static void main(String[] args) {
			final StringBuffer s1 = new StringBuffer();
			final StringBuffer s2 = new StringBuffer();
			new Thread() {
				public void run() {
					synchronized (s1) {
						s2.append("A");
						synchronized (s2) {
							s2.append("B");
							System.out.print(s1);
							System.out.print(s2);
						}
					}
				}
			}.start();
		}
	}

πŸ”₯ Synchronized vs lock

  1. Lock is an explicit lock (manually opening and closing the lock), and synchronized is an implicit lock, which is automatically released out of the scope
  2. Lock only has code block lock, and synchronized has code block lock and method lock
  3. With Lock lock, the JVM will spend less time scheduling threads and have better scalability (providing more subclasses)

🎁 Note: it must be ensured that multiple threads using the same resource share a lock

5, Thread communication

πŸ”₯wait(),notify(),notifyAll()

  1. wait(): make the current thread release the object monitoring right, and then enter the wait mode
  2. notify(): wakes up the thread with the highest priority waiting for synchronization resources and ends the wait
  3. notifyAll(): wakes up all threads queued for resources and ends waiting

Portal > > > Master Kang's classic example: Producer / consumer issues

These three methods can only be used in the synchronized method or synchronized code block, otherwise it will report Java Lang.illegalmonitorstateexception

🎁 Summary: multithreading is difficult for me to understand and use. Please read the summary several times
πŸ‘Œ The author is a Java beginner. If there are errors in the article, please comment and correct them in private letters and learn together~~
😊 If the article is useful to the friends, praise it πŸ‘ follow πŸ”Ž Collection πŸ” Is my biggest motivation!
🚩 Step by step, nothing to a thousand miles, book next time, welcome to see you again 🌹

Keywords: Java Back-end

Added by bradymills on Wed, 19 Jan 2022 03:03:38 +0200