This is the 31st day of my participation in the August More Text Challenge

1. Procedures, processes, threads

1.1 the program

A set of instructions written in a language to accomplish a specific task, a static piece of code

1.2 process

It is an execution of a program, or a running program, a dynamic process

Create – exist – Die

1.3 the thread

Is part of the process, is an execution path within the program

Each thread has its own run stack and program counter

Process is the basic unit of program running and resource allocation.

Threads are the basic unit of CPU scheduling and dispatch that can operate independently.

Parallel, concurrent

  • Parallel: Multiple cpus perform multiple tasks at the same time. For example: more than one person at a time
  • Concurrency: a CPU executes multiple tasks simultaneously (using a time slice mechanism), operating on the same resource. For example: second kill, more than one person to do the same thing

2, the Thread

Thread creation 1:

Inherit Thread and override the run() method.

  • Cannot be called directlyrun()Method to start a thread, which simply calls a class’s normal method;
  • We can’t let it happen againstart()The thread is called againstart()Method, an exception will be reportedIllegalThreadStateException.

2.1 Common Methods of Thread

The method name Methods effect
void start() The thread starts execution, and the Java virtual machine calls the thread’s run method
void run() The execution content of the thread
String getName() Returns the name of this thread
void setName(String name) Set the name of this thread to parameter name
int getPriority() Returns the priority of this thread
void setPriority(int newPriority) Change the thread priority
static Thread currentThread() Returns a reference to the thread object currently executing.
static void sleep(long millis) Causes the currently executing thread to pause (temporarily stop execution) for the specified number of milliseconds.
void yield() The current thread releases execution from the CPU (and may continue immediately)

Performed)
void join() Thread B.jiin () is called in thread A and thread A is blocked

Thread A does not stop blocking until thread B has finished executing
Void stop() (deprecated) The stop line

2.2 Thread scheduling

2.2.1 Scheduling Policies

Time slice: preemptive, preemption of CPU execution according to thread priority, higher priority is easier to obtain; Same priority thread, first in first out queue.

2.2.2 Priority level

  • MAX_PRIORITY:10
  • MIN_PRIORITY:1
  • NORM_PRIORITY:5 (default)

Usage:

  • Void setPriority(int priority) : sets the thread priority
  • Int getPriority() : gets the thread priority

Then pay attention to

  • Thread creation inherits its parent thread priority;
  • A low priority is simply a low probability of getting a CPU schedule, and is not necessarily called after a high priority thread.

2.3 Classification of threads

  • Daemon thread: serves the user thread (main thread), such as Java garbage collection;
    • If the JVM is full of daemons, the current JVM exits.
  • User thread (main thread)
    • instart()Pre-method callthread.setDaemon(true)You can turn a user thread into a daemon thread.

3. Synchronization mechanism of threads

1. Synchronize code blocks

synchronized(Synchronization monitor){// Code that needs to be synchronized: statements that threads operate on shared data
}
Copy the code
  • Code that operates on shared data is code that needs to be synchronized (no more code, no less code);
  • Shared data: variables that multiple threads operate on in common;
  • Synchronization monitor, commonly known asThe lock. An object of any class can act as a lock;But multiple threads must share the same lock;
  • Thread inherits the class, commonly usedThe name of the current class.classAs a synchronization monitor;
  • Runnable interface implementation class, you can consider usingthisAct as synchronization monitor

2. Synchronization method

If the code that operates on shared data is fully declared in a method, you can use the declaration to synchronize the entire method

  • The synchronization method is still designed to the synchronization monitor, but we don’t need to declare it explicitly;
  • Non-static synchronization methods, synchronization monitors are:this;
  • Static synchronization methods, synchronization monitors are:The current class itself;

3, the Lock locks

java.util.concurrent.locks.lock

Implementation class:

Already,

ReentrantReadWriteLock ReaLock,

​ ReentrantReadWriteLock.WriteLock

  • Starting with JDK 5.0, Java provides a more powerful thread synchronization mechanism by explicitly defining a synchronization lock object. A synchronous Lock uses the Lock object to act as a Lock;

  • Java. Util. Concurrent. The locks. Lock interface is the tool of control multiple threads to Shared resources access;

    A Lock provides independent access to a shared resource. Only one thread can Lock the Lock object at a time. The thread must acquire the Lock object before accessing the shared resource.

  • The ReentrantLock class implements Lock, which has the same concurrency and memory semantics as Synchronized. In implementing thread-safe control, ReentrantLock is commonly used, which can explicitly Lock and release the Lock.

implementation

  • Start synchronization: lock();
  • End synchronization: unlock().

ReentrantLock

Fair lock: first come, last served

Unfair lock: You can jump the queue (default)

4. Advantages and disadvantages of threads

  • The synchronization method solves the safety problem of the thread. — > benefits
  • When manipulating synchronized code, only one thread can participate, while the other threads wait. It’s a single-threaded process, which is inefficient. — > limitations

4. Thread communication

Wait () : Once this method is executed, the current thread blocks and releases the synchronization monitor;

Notify () : This method wakes up one of the threads being waited, or one of the threads being waited with the highest priority.

NotifyAll () : Once this method is executed, all threads being waited are awakened.

Description:

  • Wait (), notify(), and notifyAll() must be used in synchronized code blocks or synchronized methods.

  • The callers of wait(), notify(), and notifyAll() must be synchronized blocks or synchronization monitors in synchronized methods.

    Otherwise, there will be a IllegalMonitorStateException anomalies

Producer/consumer issues

The Productor gives the product to the Clerk, and the Customre takes it from the Clerk, who can only hold a fixed number of products at a time (e.g. 20), if the producer view produces more products, the clerk will ask the producer to stop for a while, and notify the producer to continue production if there is room for more products in the store; If there is no product in the store, the clerk will tell the consumer to wait, if there is a product in the store to inform the consumer to pick up the product.

They are both producers.

// Producer: controls product objects
class Producer extends Thread{
    private Product product;
    public Producer(a){}public Producer(Product product){
        this.product = product;
    }

    // Make a product
    public void run(a){
        System.out.println("Production products ================");
        // Call the product method to produce
        while(true) {try {
                Thread.sleep(10);
            } catch(InterruptedException e) { e.printStackTrace(); } product.production(); }}}Copy the code

A Consumer

// Consumer: controls product objects
class Consumer extends Thread{
    private Product product;
    public Consumer(a){}public Consumer(Product product){
        this.product = product;
    }

    // Buy the product
    public void run(a){
        System.out.println("Buy products ================");
        // Call the product method to sell
        while(true) {try {
                Thread.sleep(100);
            } catch(InterruptedException e) { e.printStackTrace(); } product.sell(); }}}Copy the code

Product (Product)

/ / product
class Product{
    private int productCount = 0;
    private Object sync = new Object();
    // Make a product
    public synchronized void production(a){
            if(productCount < 20){
                productCount++;
                System.out.println(Thread.currentThread().getName() + "-- Production control" + productCount + "Piece of merchandise");
                notify();
            } else{
                System.out.println(Thread.currentThread().getName() + "-- If number of products > 20, wait() to execute");
                try {
                    wait();
                } catch(InterruptedException e) { e.printStackTrace(); }}}/ / sell
    public synchronized void sell(a){
            if(productCount > 0){
                System.out.println(Thread.currentThread().getName() + "*** purchased the no." + productCount + "Piece of merchandise");
                productCount--;
                notify();
            } else{
                System.out.println(Thread.currentThread().getName() + "-- No more items, wait() to execute");
                try {
                    wait();
                } catch(InterruptedException e) { e.printStackTrace(); }}}}Copy the code

To start (producing, consuming) :

public class ProductTest {

    public static void main(String[] args) {
        Product product = new Product();
        / / production line
        Producer producer = new Producer(product);
        producer.setName("Producer");
        // Consume line 1
        Consumer consumer1 = new Consumer(product);
        consumer1.setName("Consumer 1");
        // Consume line 2
        Consumer consumer2 = new Consumer(product);
        consumer2.setName("Consumer 2"); producer.start(); consumer1.start(); consumer2.start(); }}Copy the code

Create thread-3: Implement the Callable interface

Create thread in JDK 5.0

  1. implementationCallableInterface;
  2. Using thread pools

Callable is more powerful than Runnable

  • Compared with therun()Method, which can have a return value;
  • Method can throw an exception;
  • Support for generic return values;
  • Need to useFutureTaskClass, such as getting the return result

The Future interface

  • Can be specific toRunnable,CallableCancel the execution result of the task, query whether the task is completed, and obtain the result.
  • FutureTaskisFutureThe unique implementation class of the interface;
  • FutureTakAt the same timeRunnable,FutureInterface, which can be used as bothRunnableNorth county execution, and can serve asFuturegetCallableThe return value of the

Implementation steps

  1. Create an implementation class that implements the Callable interface and implements generics, the return value type of the Call () method;

  2. Implement the call() method to declare the operations this thread needs to perform in call();

    // create a generic class that implements the Callable interface
    class NumThread implements Callable<Integer>{
    
        @Override
        public Integer call(a) throws Exception {
            System.out.println(Thread.currentThread().getName() + "Execution -- -- -- -- --");
            int sum = 0;
            for(int i = 0; i < 100; i++){
                if(i % 2= =0){ sum += i; }}returnsum; }}Copy the code
  3. Create an object for the Callable interface implementation class.

  4. The object of the FutureTask is created by passing the object of the Callable interface implementation class as a parameter to the FutureTask constructor.

  5. Pass the object of FutureTask as an argument to the constructor of the Thread class, create the Thread object, and call the start() method.

  6. Gets the return value of the Call () method in the Callable interface implementation class.

    public class Callable_Test {
    
        public static void main(String[] args) {
            // 3. Create an object for the 'Callable' interface implementation class;
            NumThread numThread = new NumThread();
            // 4. Pass the object of the 'Callable' interface implementation class as a parameter to the 'FutureTask' constructor to create the object of 'FutureTask';
            FutureTask<Integer> futureTask = new FutureTask<Integer>(numThread);
    		// 5. Pass the 'FutureTask' object as an argument to the 'Thread' constructor, create the 'Thread' object and call the 'start()' method.
            Thread thread = new Thread(futureTask);
            thread.start();
    
            try {
                // 6. Get the return value of the call() method in the Callable interface implementation class.
                Integer sum = futureTask.get();
               System.out.println(sum);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch(ExecutionException e) { e.printStackTrace(); }}}Copy the code

Create thread-4: Use a thread pool

Background: Heavily used resources that are frequently created and destroyed, such as threads in the case of concurrency, can have a big impact;

Create multiple threads in the terraced field and put them into the thread pool. It can avoid frequent creation and destruction and realize reuse.

Benefits:

  1. Increased speed (reduced time to create new threads);

  2. Reduce resource consumption (reusing threads from the thread pool, not creating them every time);

  3. Easy thread management

The relevant API

JDK 5.0 provides thread pool-related apis: ExecutorService interface, Executors tools

  • ExecutorService: True thread pool interface, common subclassesThreadPoolExecutor
    • Void execute(Runnable command) : Executes a task or command. No return value is returnedRunnable;
    • Future Submit (Callable Task) : Performs a task, returns a value, and is generally used for executionCallable
    • Void shutdown() : shuts down the connection pool
  • Executors: Factory classes for tools and thread pools, used to create and return different types of thread pools
    • Executors. NewCachedThreadPool () : create a according to the need to create a new thread’s thread pool, but when available will use structure before thread;
    • Executors. NewFixedThreadPool (int nThreads) : create a reusable fixed number of threads thread pool;
    • Executors. NewSingleThreadExecutor () : create a use of unbounded queue run a single worker threads to perform a task;
    • Executors. NewScheduledThreadPool (int corePoolSize) : create a thread pool, can run for scheduling command after the given delay, or run on a regular basis

Implementation steps

public class Executors_Test {
    public static void main(String[] args) {
        // Provide the thread pool for the specified number of threads. // Return the ThreadPoolExecutor class according to the Executors tool
        ThreadPoolExecutor --> inherits AbstractExecutorService --> implements ExecutorService
        ThreadPoolExecutor service = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        The ThreadPoolExecutor class can use more methods to manage thread pools. Such as:
        service.setCorePoolSize(20);
// service.setKeepAliveTime(long time,TimeUnit unit);
// service.setMaximumPoolSize(30);
// service.setRejectedExecutionHandler(RejectedExecutionHandler handler);
// service.setThreadFactory(ThreadFactory factory);

        // 2. To perform the specified thread operation, you need to provide the implementation class of the Runnable interface or the Callable interface
        System.out.println(service.getClass());

        // 2.1 Implement classes using the Runnable interface
        service.execute(new Number_Runnable());

        // 2.2 Implements the class using the Callable interface and returns a value
        Future<Integer> future = service.submit(new Number_Callable());
        try {
            int sum = future.get();
            System.out.println("Callable implementation class gets return value" + sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        // 3. Close the connection poolservice.shutdown(); }}/ / implementation Runnable
class Number_Runnable implements Runnable{

    @Override
    public void run(a) {
        int sum = 0;
        for (int i = 0; i < 100; i++){
            if(i % 2= =0){
                System.out.println(Thread.currentThread().getName() + "--" + i);
                sum += i;
            }
        }
        System.out.println("Runnable-- the even sum up to 100 is:"+ sum); }}// Implement Callable and use generics to control the return value type
class Number_Callable implements Callable<Integer> {

    @Override
    public Integer call(a) throws Exception {
        int sum = 0;
        for (int i = 0; i < 100; i++){
            if(i % 2= =1){
                System.out.println(Thread.currentThread().getName() + "--"+ i); sum += i; }}returnsum; }}Copy the code

The interview questions

1. The difference between synchronized and Lock

  • Same: Both address thread-safety issues
  • Not the same:
    • synchronizedIs the built-in Java keyword;LockIs a Java class;
    • synchronizedThe mechanism automatically releases the lock after executing the corresponding synchronized code block.LockManual synchronization is required (lock()), and termination of synchronization also requires manual implementation (unlock()).
    • synchronizedReentrant lock, can not break, unfair;LockReentrant lock, determinable lock, not fair (can be set yourself)
      • Reentrant lock: if the thread acquires the lock from the outer method, the inner method of the thread will automatically acquire the lock (provided that the lock object is the same object or class). The lock will not block because it has been acquired before and has not been released.
  • Priority order: Lock –> synchronize code block (already in method body, allocated resources) –> synchronize method (outside method body)

2,sleep()withwait()The difference between

  1. sleep()Methods belong to the Thread class; whilewait()Method, belongs to the Object class;
  2. sleep()Methods can be called anywhere else;wait()Can only be called in synchronized code blocks;
  3. sleep()Method causes a program to pause execution for a specified time, freeing the CPU for another thread, but its monitoring state remains and automatically resumes when the specified time is up. So when you callsleep()In the process of the method,The thread does not release the object lock;
  4. callwait()When it comes to methods,The thread gives up the object lock, into the pool of wait locks waiting for this thread, only called for this objectnotify()ornotifyAll()Method before the thread enters the object lock pool to obtain the object lock and enter the running state.Pay attention to: After awakening, will be inwait()Continue to execute.