Exception and multithreading review

Posted by disconne on Tue, 01 Feb 2022 00:10:39 +0100

1, Abnormal

1.1 concept of abnormality

Exception: it is an abnormal condition that occurs during the execution of the program, which will eventually lead to the abnormal stop of the JVM.

In object-oriented programming languages such as java, the exception itself is a class. Generating an exception is to create an exception object and throw an exception object.

The way java handles exceptions is interrupt handling

The exception is not a syntax error. If the syntax is wrong, it will not pass during compilation. If it does not pass, it will not generate a class (bytecode) file and cannot run at all.

1.2 abnormal system

The root class of the exception is Java Lang. throwable, which is inherited by two subclasses: Java Lang. error and Java lang.Exception. java.lang.Exception is the usual exception.

Throwable system:

  • Error: fatal error, an error that cannot be processed.
  • Exception: indicates an exception during compilation. After an exception is generated, it can be corrected by code.

1.3 analysis of abnormal process

2, Exception handling

Five keywords for java exception handling: try, catch, finally, throw, throws

2.1 throw exception

Throw is used in a method to throw an exception object, pass the exception object to the caller, and end the execution of the current method.

Use format:

throw new Exception class name(parameter)

2.2 non empty objects judgment

Check whether the specified reference object is null

public static<T>T requireNonNull(T obj) 

2.3 declare exception throws

The keyword throws is used on the method declaration to indicate that the current method does not handle exceptions, but reminds the caller of the method to handle exceptions (throw exceptions).

**Declare exception: * * identify the problem table and report it to the caller.

Format:

Modifier return value type method name (parameter) throws Exception class name 1, exception class name 2...{...}
public class ThrowsDemo{
    public static void main(String[] args) throws FileNotFoundException{
        read.("a.txt");
    }
    
    public static void read(String path) throws FileNotFoundException{
        if(!path.equals("a.txt")){
            throw new FileNotFoundException("File does not exist!");
        }
    }
}

2.4 catch exception try catch

If an exception occurs, the program will be terminated immediately, so we have to deal with the exception:

  1. No processing, declaration thrown. Use the throws keyword
  2. Using try catch in a method is to handle exceptions

The way to try catch is to catch exceptions.

Catch exception: in java, targeted statements of exceptions are caught, and exceptions can be handled in a specified way

Format:

try{
    //Code that may cause exceptions
} catch{
    //Logic of exception handling
}

Supplement:

  1. Multiple exceptions may be thrown in try, so multiple catch es are needed to handle exceptions.
  2. If an exception occurs in try, the catch exception handling logic will be executed and the code after catch will run normally; If there is no exception in try, catch will not be executed and the subsequent code will continue to be executed.

2.5 finally

finally cannot be used alone and will be executed regardless of whether an exception occurs

Use with try catch.

Throwable supplement

  • public String getMessage(): returns the detailed message string of this throwable (the string may be null)

  • public String toString():

    Returns a short description of this throw. The result is:

    • The name of the class of this object
    • ":" (a colon and a space)
    • The result of calling the getLocalizedMessage() method of this object

    If getLocalizedMessage returns null, only the class name is returned.

  • public void printStackTrace(): the JVM prints exception objects. By default, this method prints the most comprehensive exception information.

3, Multithreading

3.1 concurrency and parallelism

Concurrency: it refers to that multiple tasks are executed at the same time in the same time period, and none of them is finished. Concurrent tasks emphasize the simultaneous execution in a time period, and a time period is accumulated by multiple unit times. Therefore, multiple concurrent tasks may not be executed at the same time in a unit time.
Parallel: it means that multiple tasks are executed at the same time in unit time.

  • Concurrency: refers to the occurrence of two or more events within the same time period. (alternate execution)
  • Parallel: two or more events occur at the same time. (executed simultaneously)

3.2 threads and processes

  • Process: it is an execution of a program and the smallest unit (basic unit) of operating system resource allocation and scheduling. A system running a program is a process from creation, running to extinction.

  • Thread: a thread is an execution unit in a process, which is responsible for the execution of programs in the current process. A process has at least one thread. There can be multiple threads in a process, and this application can also be called a multithreaded program.

Relationship between the two: process refers to an instance of program execution, and thread is an entity of process.

3.2.1 difference between thread and process

Process:

  • With independent stack space and data segments, the system overhead is large
  • Because processes are independent, the security of processes is relatively high. There is an independent address space. The collapse of one process will not affect other processes
  • The communication mechanism of process is relatively complex, such as pipeline, signal, message queue, socket and so on

Thread:

  • Threads have independent stack space, but share data segments. They use the same address space with each other, which is less expensive than the process
  • Threads are different execution paths in a process. The death of a thread is equal to the death of the whole process.
  • Communication is relatively convenient

3.2.2 thread life cycle

  1. New state: after the thread object is created, it enters the new state, for example: Thread t = new Thread();
  2. Runnable: when calling the start() method of the thread object (example: t.start();), The thread enters the ready state. A thread in the ready state only indicates that the thread is ready to wait for the CPU to schedule execution at any time, not immediately.
  3. Running: when the CPU starts scheduling the thread in the ready state, the thread can really execute, that is, enter the running state. Note: the ready state is the only entry to the running state, that is, if a thread wants to enter the running state for execution, it must first be in the ready state;
  4. Blocked: the thread in the running state temporarily gives up the right to use the CPU and stops execution for some reason. At this time, it enters the blocking state. Until it enters the ready state, it has the opportunity to be called by the CPU to enter the running state again. According to different causes of blocking, blocking states can be divided into three types:
    • Wait blocking: the thread in the running state executes the wait() method to make the thread enter the wait blocking state;
    • Synchronization blocking: when a thread fails to obtain a synchronized synchronization lock (the lock is occupied by other thread locks), it will enter the synchronization blocking state;
    • Other blocking: by calling the thread's sleep () or join(), or issuing an I/O request, the thread will enter the blocking state. When the sleep() state times out, the join waits for the thread to terminate or time out, or the I/O processing is completed, the thread will return to the ready state;
  5. Dead state: when the thread finishes executing or exits the run() method due to an exception, the thread ends the cycle.

3.2.3 thread scheduling

  • Time sharing scheduling: all threads use the right to use the CPU in turn, and allocate the CPU time of each thread equally

  • Preemptive scheduling: give priority to the threads with high priority to use CPU. If the threads have the same priority, one will be selected randomly (thread randomness), and java uses preemptive scheduling.

3.3 create thread class

java uses java Lang. Thread class represents threads. All Thread objects must be instances of Thread class or its subclasses

The steps to create and start a multithread by inheriting the Thread class in java are as follows:

  1. Define the subclass of Thread class and override the run () method of this class. The method body of the run () method represents the task that the Thread needs to complete. Therefore, the run () method is called the Thread executor.
  2. Create an instance of Thread subclass, that is, create a Thread object.
  3. Call the start() method of the thread object to start the thread.

3.3.1 principle of multithreading

3.4 Thread class

A thread is a thread that executes in a program. The Java virtual machine allows applications to execute multiple execution threads simultaneously.

Each Thread has priority. Threads with higher priority take precedence over threads with lower priority. Each Thread may or may not be marked as a daemon. When code running in a Thread creates a new Thread object, the priority of the new Thread is initially set to be equal to the priority of the creating Thread, and it is a daemon if and only if the creating Thread is a daemon.

When the Java virtual machine starts, there is usually a non daemon thread (usually calling the method named main of some specified classes). The Java virtual machine will continue to execute the thread until any of the following occurs:

  • The exit method of the Runtime class has been called, and the security manager has allowed the exit operation.
  • All threads that are not daemon threads have died, whether returning from the call to the run method or throwing a run beyond the run method.

Construction method:

Common methods:

  • public String getName();– Gets the name of the current thread
  • public String setName(String name);– Change the current thread name to parameter name
  • public void start(); – Cause this thread to start execution; The Java virtual machine calls the run method of this thread.
  • public void run(); – If this thread is constructed with a separate Runnable running object, call the run method of the Runnable object; Otherwise, this method does nothing and returns.
  • public static void sleep(long millis);– Pauses the currently executing thread for the specified number of milliseconds (temporarily stops execution), depending on the accuracy and accuracy of the system timer and scheduler.
  • public static Thread currentThread();– Returns a reference to the thread object currently executing.
  • public void setPriority(int newPriority); -- Change the priority of this thread to a minimum of 1 and a maximum of 10.

3.5 thread creation mode 2

Using Java Lang. runnable is a common method

The steps are as follows:

  1. Define the implementation class of Runnable interface and rewrite the run() method of the interface. The method body of the run() method is also the thread execution body of the thread.
  2. Create an instance of the Runnable implementation class and use this instance as the target of the Thread to create the Thread object, which is the real Thread object.
  3. Call the start() method of the thread object to start the thread.

The case code is as follows:

public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("residential quarters"+i);
            try {

            Thread.sleep(1000);
            } catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
public class RunnableDemo {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        new Thread(myRunnable).start();
    }
}

3.6 difference between thread class and Runnable interface

If a class inherits Thread, it is not suitable for resource sharing. However, if the Runnable interface is implemented, it is easy to realize resource sharing.

Advantages of implementing Runnable interface over inheriting Thread class:

  1. It is suitable for multiple threads of the same program code to share a resource.
  2. It can avoid the limitation of single inheritance in java.
  3. Enhance the robustness of the program and realize decoupling operation. The code can be shared by multiple threads, and the code and threads are independent.
  4. The Thread pool can only put threads that implement Runnable or Callable classes, not directly into classes that inherit threads.

Extension: in java, at least 2 threads are started each time the program runs. One is the main thread and the other is the garbage collection thread. Because whenever a class is executed with java commands, a JVM is actually started, and each JVM is a process started in the operating system.

3.7 creating threads by anonymous inner classes

public class InnerClassThread {
    /*
    The creation of thread is realized by anonymous internal class
    Anonymous inner class function: inherit the subclass from the parent class, override the parent class method, and create the subclass object in one step with the same interface.

    Format:
    new Parent class / interface (){
        Rewrite method;
    }
     */

    public static void main(String[] args) {
        //The first way to create a thread:
        //MyThread extend Thread
        //MyThread mt = new MyThread();
        //mt.start();
        new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    System.out.println(Thread.currentThread().getName()+"-->"+i);
                }
            }
        }.start();
        //The second method: Runnable interface
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    System.out.println(Thread.currentThread().getName()+"programmer"+i);
                }
            }
        }).start();
    }
}

3.8 thread pool

/**
 * Java Four thread pools are provided through Executors:
 * newCachedThreadPool Create a cacheable thread pool. If the length of the thread pool exceeds the processing needs, you can flexibly recycle idle threads. If there is no recyclable thread, you can create a new thread.
 * newFixedThreadPool Create a fixed length thread pool to control the maximum concurrent number of threads. The exceeded threads will wait in the queue.
 * newScheduledThreadPool Create a fixed length routing pool to support regular and periodic task execution.
 * newSingleThreadExecutor Create a singleton thread pool, which will only use a unique working thread to execute tasks, and ensure that all tasks are executed in the specified order (FIFO, LIFO, priority).
 */
public class TestPool {
    public static void main(String[] args) {
        //Create service and thread pool
        //Size of thread pool fixedthreadpool
        ExecutorService service = Executors.newFixedThreadPool(10);


        service.execute(new MyThreade());
        service.execute(new MyThreade());
        service.execute(new MyThreade());
        //End of service
        service.shutdown();

    }
}

class MyThreade implements Runnable{
    @Override
    public void run() {
       System.out.println(Thread.currentThread().getName());
    }
}

4, Thread safety

4.1 thread safety cases

Case: ticket selling in cinema

public class RunnableImp implements Runnable{
    //Define the number of votes
    private Integer ticket = 100;

    /**
     * Ticket selling operation
     */
    @Override
    public void run() {
        while(true){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (ticket > 0){
                System.out.println(Thread.currentThread().getName()+"Is selling"+ticket+"ticket");
                ticket--;
            }
        }
    }
}

public class ThreadDemo {
    public static void main(String[] args) {
        
        RunnableImp runnableImp = new RunnableImp();

        new Thread(runnableImp,"Window 1").start();
        new Thread(runnableImp,"Window 2").start();
        new Thread(runnableImp,"Window 3").start();
        //This can be done using anonymous inner classes
    }
}
Window 1 is selling the 100th ticket
 Window 3 is selling the 100th ticket
 Window 2 is selling the 100th ticket
 Window 2 is selling the 97th ticket
 Window 1 is selling the 97th ticket
 Window 3 is selling the 97th ticket
 Window 2 is selling ticket 94
 Window 3 is selling the 94th ticket
 Window 1 is selling ticket 94
 Window 1 is selling ticket 91
 Window 3 is selling ticket 91

Two problems were found in the program:

  1. The same number of votes, such as 91, was sold twice.
  2. Nonexistent votes, such as 0 votes and - 1 votes, do not exist.
    In this case, the number of votes in several windows (threads) is out of sync. This problem is called thread insecurity.

4.2 thread synchronization

When multiple threads are used to access the same resource, and there are write operations on the resource in multiple threads, thread safety problems are easy to occur.

To solve the security problem of multi-threaded concurrent access to a resource in the above movie case: that is, to solve the problem of duplicate tickets and non-existent tickets, Java provides a synchronized mechanism to solve it.

In order to ensure that each thread can perform atomic operations normally, java introduces thread synchronization mechanism.

There are three ways to complete the synchronization operation:

  1. Synchronize code blocks.
  2. Synchronization method.
  3. Locking mechanism.

4.3 synchronization code block

  • Synchronized code block: the synchronized keyword can be used in a block in the method to indicate that mutually exclusive access is only realized to the resources in this area.

    Format:

    synchronized(Synchronous lock){
        Code requiring synchronous operation
    }
    

    Synchronous lock:

    The synchronization lock of an object is just a concept. You can imagine marking a lock on an object.

    1. The lock object can be of any type.

    2. Multiple thread objects should use the same lock.

      Note: at most one thread is allowed to have a synchronization lock at any time. Whoever gets the lock enters the code block. Other threads can only wait outside to release the lock.

public class RunnableImp implements Runnable{
    //Define the number of votes
    private Integer ticket = 100;
	//Definitional lock
    Object obj = new Object();
    /**
     * Ticket selling operation
     */
    @Override
    public void run() {
        while(true){
            synchronized(obj){
                if (ticket > 0){
                    System.out.println(Thread.currentThread().getName()+"Is selling"+ticket+"ticket");
                    ticket--;
                }
            }
        }
    }
}

Note: the program will frequently judge the lock and release the lock, which will lead to low program efficiency.

4.4 synchronization method

  • Synchronization method: the method modified by synchronized is called synchronization method, which ensures that when thread A executes this method, other threads can only wait for the release of the lock outside the method.

Format:

public synchronized void method(){
    Code that may cause thread safety problems
}

Who is the synchronization lock?
For non static methods, the synchronization lock is this.
For static methods, we use the bytecode object (class name. class) of the class where the current method is located.

/**
 * Use steps:
 *  1. Extract the code that accesses the shared data and put it into a method.
 *  2. Add the synchronized modifier to the method
 */
public class RunnableImp implements Runnable{
    //Define the number of votes
    private Integer ticket = 100;

    /**
     * Ticket selling operation
     */
    @Override
    public void run() {
        while(true){
           payTicket();
        }
    }

    public synchronized void payTicket(){
        try {
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (ticket > 0){
            System.out.println(Thread.currentThread().getName()+"Is selling"+ticket+"ticket");
            ticket--;
        }
    }
}

4.5 Lock lock

java.util.concurrent.locks.lock mechanism provides a wider range of locking operations than synchronized code blocks and synchronized methods. Both synchronized code blocks and synchronized methods have lock functions.

Lock lock is also known as synchronous lock. The locking and releasing methods are as follows:

  • public void lock(); Add synchronization lock.
  • public void unlock; Release the synchronization lock.
public class RunnableImp implements Runnable{
    //Define the number of votes
    private Integer ticket = 100;
    Lock l = new ReentrantLock();

    /**
     * Ticket selling operation
     */
    @Override
    public void run() {
        while(true){
            l.lock();  //Acquire lock
            try {
                Thread.sleep(20);
                if (ticket > 0){
                    System.out.println(Thread.currentThread().getName()+"Is selling"+ticket+"ticket");
                    ticket--;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                l.unlock(); //Release lock
            }
            
        }
    }
}

5, Thread state

In the API, Java lang.Thread. State this enumeration class gives six thread states:

Thread stateCauses the status to change
New (New)The thread has just been created but not started. The start() method has not been called.
RunnableThe thread state of the runnable thread. A runnable thread is executing in the Java virtual machine, but it may be waiting for other resources from the operating system, such as the processor.
BlockedThe thread state of a thread is blocked waiting for the monitor to lock. The blocked thread is waiting for the monitor lock to enter the synchronization block / method, or is calling object After wait, re-enter the synchronized block / method.
Waiting (unlimited waiting)Thread state of waiting thread the thread is in waiting state due to calling one of the following methods: 1 Object. The wait did not time out. 2.Thread. The join did not time out. 3. LockSupport.park . A waiting thread is waiting for another thread to perform a specific action. For example, object. Has been called on an object The wait () thread is waiting for another thread to call the object on the object notify() Object. Notifyall() or call thread The thread of join() is waiting for the specified thread to terminate.
Timed waitingIn the same waiting state, several methods have timeout parameters. Calling them will enter the Timed Waiting state. This state will remain until the timeout period expires or a wake-up notification is received. A common method with timeout parameters is thread sleep ,Object.wait.
TerminatedDie because the run method exits normally, or die because an uncapped exception terminates the run method.

6, Waiting and wake-up mechanism

6.1 inter thread communication

Concept: multiple threads are processing the same resource, but the thread tasks are different.

6.1.1 why should we handle the communication between threads

When multiple threads execute concurrently, the CPU switches threads randomly by default. When we need multiple threads to complete a task together and execute regularly, we need multi-threaded coordinated communication.

6.2 waiting for wake-up mechanism

6.2.1 what is the waiting wake-up mechanism

After a thread has performed the specified operation, it will enter the wait state (wait()), wait for other threads to wake up after executing their specified code (notify()); When there are multiple threads waiting, you can use notifyAll() to wake up all waiting threads if necessary.

wait/notify is a cooperative mechanism between threads.

6.2.2 method of waiting for wake-up

The wake-up waiting mechanism is used to solve the problem of inter thread communication. The meanings of the three methods used are as follows:

  1. Wait: when the thread enters sleep, it no longer participates in scheduling and enters the wait set. Therefore, it will not waste CPU resources and compete for locks. At this time, the thread is WAITING. It also waits for other threads to execute the notify. The thread WAITING on this object is released from the wait set and re entered into the ready queue
  2. notify: select a thread in the wait set of the notified object to release; For example, when a restaurant has a free seat, the customer waiting for the longest meal takes the first seat.
  3. notifyAll: release all threads on the wait set of the notified object.

be careful:

Even if only one waiting thread is notified, the notified thread cannot resume execution immediately, because the place where it was interrupted was in the synchronization block, and now it does not hold the lock, so it needs to try to obtain the lock again (it is likely to face competition from other threads). After success, it can resume execution where it called the wait method.

The summary is as follows:

  • If the lock can be obtained, the thread will change from WAITING state to RUNNABLE state;
  • Otherwise, when it comes out of the wait set and enters the entry set, the thread will change from the WAITING state to the BLOCKED state

Details of calling wait and notify methods

  1. The wait method and notify method must be called by the same lock object. Because: the corresponding lock object can wake up the thread after using the wait method called by the same lock object through notify.
  2. The wait method and notify method are methods belonging to the Object class. Because: the lock Object can be any Object, and the class of any Object inherits the Object class.
  3. The wait method and notify method must be used in the synchronization code block or synchronization function. Because: these two methods must be called through the lock object.

6.3 producer and consumer issues

The waiting wake-up mechanism is actually a classic problem of "producers and consumers".

Steamed stuffed bun case analysis:

Steamed stuffed bun shop threads produce steamed stuffed buns, and eating threads consume steamed stuffed buns. When there is no steamed stuffed bun (the status of steamed stuffed bun is false),The eating thread waits, and the baozi shop thread produces baozi (that is, the baozi status is true),And notify the eating thread (release the waiting state of eating),Because there are already steamed stuffed buns, the steamed stuffed buns shop thread enters the waiting state. Next, whether the eating thread can further execute depends on the acquisition of the lock. If the lock is obtained from the food, the action of eating steamed stuffed buns is executed, and the steamed stuffed buns are finished (the status of steamed stuffed buns is false),And notify the thread of the baozi shop (release the waiting state of the baozi shop),The eating thread is waiting. Whether the packet shop thread can further execute depends on the acquisition of the lock.

Case code:

public class Main {
    public static void main(String[] args) {
        Bun bun = new Bun();

        new Producer(bun).start();
        new Consumer(bun).start();
    }
}

public class Consumer extends Thread{

    private Bun bun;

    public Consumer(Bun bun){
        this.bun = bun;
    }


    @Override
    public void run() {
        while (true){
            synchronized (bun){
                if (bun.flag == false){
                    //No steamed stuffed bun
                    try {
                        bun.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //Awakened thread
                System.out.println("Consumer is buying"+bun.BunSkin+bun.Stuffing+"steamed stuffed bun");
                System.out.println("=================================================");
                //modify state
                bun.flag = false;
                bun.notify();
                System.out.println("To produce steamed stuffed buns");
            }
        }
    }
}
public class Producer extends Thread{
    //Create package variables
    private Bun bun;
    //The composition method assigns a value to the steamed stuffed bun
    public Producer(Bun bun){
        this.bun = bun;
    }

    @Override
    public void run() {
        int count = 0;
        while (true){
            synchronized(bun){
                //Wait for steamed stuffed buns
                if (bun.flag == true){
                    try {
                        bun.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //After being awakened, the steamed stuffed bun shop produces steamed stuffed buns and alternately produces two steamed stuffed buns
                if (count%2 == 0){
                    //Production of meat bags
                    bun.BunSkin ="Crispy";
                    bun.Stuffing="Seafood stuffing";
                } else {
                    bun.BunSkin ="Thin skin";
                    bun.Stuffing="Leek stuffing";
                }
                count++;
                System.out.println("Steamed stuffed buns are in production"+bun.BunSkin+bun.Stuffing+"steamed stuffed bun");
                System.out.println("=================================================");
                //It takes 5 seconds to produce steamed stuffed buns
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //The steamed stuffed bun shop produces steamed stuffed buns, modifies the state of steamed stuffed buns and wakes up the consumer thread
                bun.flag = true;
                bun.notify();
                System.out.println("Steamed stuffed bun shop, steamed stuffed bun production is good,"+bun.BunSkin+bun.Stuffing+"Steamed stuffed bun consumer purchase");
            }
        }
    }
}

7, Thread pool

**Thread pool: * * in fact, it is a container for multiple threads, in which threads can be used repeatedly, eliminating the operation of frequently creating thread objects and consuming too many resources without repeatedly creating threads.

Benefits of rational utilization of thread pool:

  1. Reduce resource consumption. The number of threads created and destroyed is reduced. Each working thread can be reused and can perform multiple tasks.
  2. ==Improve response speed== When the task arrives, the task can be executed immediately without waiting for the thread to be created.
  3. ==Improve thread manageability== You can adjust the number of work line threads in the thread pool according to the system's affordability to prevent the server from getting tired due to excessive memory consumption (each thread needs about 1MB of memory. The more threads are opened, the more memory will be consumed, and finally crash).

7.1 use of thread pool

The top-level interface of thread pool in Java is Java util. concurrent. Executor, but strictly speaking, executor is not a thread pool, but a tool for executing threads. The real thread pool interface is Java util. concurrent. ExecutorService.

Officials recommend using the Executors project class to create thread pool objects. There is a method to create thread pool in Executors class as follows:

  • public static ExecutorService newFixedThreadPool(int nThreads): returns the thread pool object. (a bounded process pool is created, that is, the maximum number of threads in the pool can be specified). The parameter int nThreads represents the number of threads contained in the created thread pool.

After obtaining a thread pool ExecutorService object, how to use it? Here is a method to use the thread pool object as follows:

  • public Future<?> Submit (runnable task): get a thread object in the thread pool and execute the thread task.

  • void shutdown(): start orderly shutdown, in which previously submitted tasks will be executed, but no new tasks will be accepted. If closed, the call has no additional effect.

    Future interface: used to record the results generated after the execution of thread tasks. Thread pool creation and use.

public class Demo {
    public static void main(String[] args) {
        //1. The factory class Executors using thread pool provides a static method newnewFixedThreadPool(int nThreads) to produce a thread pool with a specified number of threads
        ExecutorService service = Executors.newFixedThreadPool(2);
        //2. Create a class, implement the Runnable interface, rewrite the run method, and set the thread task
        //3. Call the submit method in ExecutorService, transfer the thread task (implementation class), start the thread and execute the run method.
        //The thread pool is always open. After using the thread, it will automatically return the thread to the thread pool, and the thread can continue to be used.
        service.submit(new RunnableImp());
        //Finally, you can call the shutdown method to destroy the thread pool. (destruction is not recommended)
    }
}

8, Lambda expression

public class Demo {
    public static void main(String[] args) {
        //Anonymous Inner Class 
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"Thread 1");
            }
        }).start();

        //lambda expressions 
        new Thread(() ->{
            System.out.println(Thread.currentThread().getName()+"Thread 2");
        }).start();

        //Optimize lambda expressions
        new Thread(() ->System.out.println(Thread.currentThread().getName()+"Thread 2")).start();
    }
}

8.1 premise of lambda

Lambda's syntax is very concise, completely free from the constraints of object-oriented complexity. However, there are several problems that need special attention when using:

  1. Lambda must have an interface, and there must be only one abstract method in the interface.
    Whether it is the built-in Runnable, Comparator interface or user-defined interface of JDK, Lambda can be used only when the abstract methods in the interface exist and are unique.
  2. Using Lambda must have context inference.
    That is, the parameter or local variable type of the method must be the interface type corresponding to Lambda before Lambda can be used as an instance of the interface.

Note: an interface with only one abstract method is called "functional interface".

Inner class
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "thread 1");
}
}).start();

    //lambda expressions 
    new Thread(() ->{
        System.out.println(Thread.currentThread().getName()+"Thread 2");
    }).start();

    //Optimize lambda expressions
    new Thread(() ->System.out.println(Thread.currentThread().getName()+"Thread 2")).start();
}

}

## 8.1 premise of lambda

Lambda The syntax of is very concise, without the constraints of object-oriented complexity. However, there are several problems that need special attention when using:

1. use Lambda Must have an interface and require**There is only one abstract method in the interface**. 
   Whether it is JDK Built in`Runnable`,`Comparator`The interface is also a user-defined interface. It can be used only when the abstract methods in the interface exist and are unique Lambda. 
2. use Lambda Must have**Context inference**. 
   That is, the parameter or local variable type of the method must be Lambda Only the corresponding interface type can be used Lambda As an example of this interface.

> Note: an interface with only one abstract method is called“**Functional interface**". 

Topics: Java Multithreading Exception