Detailed explanation of JUC high concurrency programming

Posted by nelsons on Tue, 28 Dec 2021 01:49:06 +0100

JUC concurrent programming

The essence of concurrent programming: making full use of CPU resources

Question: can JAVA start threads?

No: the bottom layer is the local method and the bottom layer is C + +. Java cannot directly operate the hardware

1. How many states are there in the thread

NEW, newborn
RUNNABLE, function
BLOCKED, block
WAITING, Wait, die, etc
TIMED_WAITING, Timeout wait
TERMINATED; termination

2. Difference between wait and sleep

1. Different classes

​ wait=>Object

​ sleep=>Thread

2. Release of lock

wait: the lock will be released

sleep: no release

3. Different application ranges

wait: must be in sync code block

sleep: anywhere

4. Is exception capture required

wait: no exception capture required

sleep: required

3.LOCK lock

synchronized lock: queue, lock

package com.wdzl;

/**
 * Thread is a resource class with no attached operations
 */
public class SaleTicketDemo01 {
    public static void main(String[] args) {
        //Concurrency: multiple threads operate on the same resource and throw the resource class into the thread
        Ticket ticket = new Ticket();
        new Thread(() -> {
            for (int i=0;i<40;i++){
                ticket.sale();
            }

        }, "A").start();

        new Thread(() -> {
            for (int i=0;i<40;i++){
                ticket.sale();
            }
        }, "B").start();

        new Thread(() -> {
            for (int i=0;i<40;i++){
                ticket.sale();
            }
        }, "C").start();

    }

}

//Resource class OOP object oriented programming
class Ticket {
    private int number = 30;

    //Ticket selling method
    // synchronized code block
    public void sale() {
        synchronized (this){
            if (number > 0) {
                System.out.println(Thread.currentThread().getName() + "Sold" + (number--) + "ticket" + ",Remaining" + number + "Ticket");
            }
        }

    }

    // synchronized keyword
    public synchronized void sale2() {
      
            if (number > 0) {
                System.out.println(Thread.currentThread().getName() + "Sold" + (number--) + "ticket" + ",Remaining" + number + "Ticket");
            }
        }

    }




Lock lock (Interface)

bottom:

Fair lock: first come, first served

Unfair lock: can jump the queue (default) to improve efficiency

package com.wdzl;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * Thread is a resource class with no attached operations
 */
public class SaleTicketDemo02 {
    public static void main(String[] args) {
        //Concurrency: multiple threads operate on the same resource and throw the resource class into the thread
        Ticket2 ticket = new Ticket2();
        new Thread(() -> { for (int i=0;i<40;i++) ticket.sale(); }, "A").start();
        new Thread(() -> { for (int i=0;i<40;i++) ticket.sale(); }, "B").start();
        new Thread(() -> { for (int i=0;i<40;i++) ticket.sale(); }, "C").start();

  

    }

}

//Resource class OOP object oriented programming

/**
 * LOCK trilogy
 * 1.new ReentrantLock();
 * 2.Lock
 * 3.Unlock
 */
class Ticket2 {
    private int number = 30;
    Lock lock=new ReentrantLock();

    //Ticket selling method
    public  void sale() {
        //Lock
        lock.lock();
        try {
            if (number > 0) {
                System.out.println(Thread.currentThread().getName() + "Sold" + (number--) + "ticket" + ",Remaining" + number + "Ticket");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

}

4. Difference between synchronized and Lock

1. The built-in Java keyword of synchroniccd, Lock, is a Java class

2. Synchronized cannot determine the status of obtaining the lock. Lock can determine whether the lock has been obtained (tryLock)

3. Synchronized will release the lock automatically. Lock must release the lock manually! If the lock is not released, it will deadlock

4. Synchronized thread 1 (Lock acquisition, blocking), thread 2 (wait, silly, etc.); Lock lock does not necessarily wait; (tryLock)

5. Synchronized reentrant lock, non interruptible, unfair; Lock, reentrant lock, lock judgment, unfair (you can set it yourself)

6. Synchronized is suitable for locking a small number of code synchronization problems, and Lock is suitable for locking a large number of synchronization codes!

5. Producer consumer model

1. Synchronized version

Note: if is not used for judgment, false wake-up will occur. If is judged only once

package com.wdzl;
/**\
 * synchronized Wait for wake-up mode
 */

public class pc {
    public static void main(String[] args) {
        //Create resource object
        Data data = new Data();
        new Thread(()-> {
            for (int i=0;i<10;i++){
                try {
                    data.Increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            },"A"
        ).start();

        new Thread(()-> {
            for (int i=0;i<10;i++){
                try {
                    data.Decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"B"
        ).start();

    }

}

//Resource class

/**
 * Judgment, waiting, business, notification
 */
class Data{
    private Integer number=0;

    //add one-tenth
    public synchronized void Increment() throws InterruptedException {
        while (number!=0){
            this.wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName()+"---->"+number);
        //Notify other threads
        this.notify();
    }

    //Minus one
    public synchronized void Decrement() throws InterruptedException {
        while (number==0){
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName()+"---->"+number);

        //Notify other threads
        this.notify();
    }


}

2.Lock version

1.Lock is equivalent to synchronized

2. In synchronized, (wait,notify) is equivalent to (await, singall) in Condition

package com.wdzl;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Lock Producer consumer model
 */
public class pc2 {
    public static void main(String[] args) {

        //Create resource object
        Data2 data = new Data2();
        new Thread(()-> {
            for (int i=0;i<10;i++){
                try {
                    data.Increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A"
        ).start();

        new Thread(()-> {
            for (int i=0;i<10;i++){
                try {
                    data.Decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"B"
        ).start();

        new Thread(()-> {
            for (int i=0;i<10;i++){
                try {
                    data.Increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"C"
        ).start();

        new Thread(()-> {
            for (int i=0;i<10;i++){
                try {
                    data.Decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"D"
        ).start();


    }



}

//Resource class

/**
 * Judgment, waiting, business, notification
 */
class Data2 {
    private Integer number = 0;
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();


    //add one-tenth
    public void Increment() throws InterruptedException {
        //Lock
        lock.lock();

        try {
            while (number != 0) {
                condition.await();
            }
            number++;
            System.out.println(Thread.currentThread().getName() + "---->" + number);
            //Notify other threads
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //Unlock
            lock.unlock();
        }


    }

    //Minus one
    public void Decrement() throws InterruptedException {
        //Lock
        lock.lock();
        try {

            while (number == 0) {
                condition.await();
            }
            number--;
            System.out.println(Thread.currentThread().getName() + "---->" + number);
            //Notify other threads
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //Unlock
            lock.unlock();
        }

    }
}

3.Condition (monitor, multiple monitors can be set to realize accurate notification wake-up)

package com.wdzl;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Condition(Monitor, multiple monitors can be set to realize accurate notification (wake-up)
 */
public class pc3 {
    public static void main(String[] args) {
        Data3 data3=new Data3();
        new Thread(()-> {
            for (int i=0;i<10;i++){
                data3.Test1();
            }

            },"A"
        ).start();

        new Thread(()-> {
            for (int i=0;i<10;i++){
                data3.Test2();
            }
        },"B"
        ).start();

        new Thread(()-> {
            for (int i=0;i<10;i++){
                data3.Test3();
            }
        },"C"
        ).start();

    }
}

//Resource class
class Data3{
    private Lock lock=new ReentrantLock();
    private Condition condition=lock.newCondition();
    private Condition condition2=lock.newCondition();
    private Condition condition3=lock.newCondition();
    private int number=1;

    public void Test1(){
        lock.lock();
        try {
           //Business code, judgment, waiting, business, notification
            while (number!=1){
                condition.await();
            }

            System.out.println(Thread.currentThread().getName()+"--------->"+number);
            number++;
            condition2.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void Test2(){
        lock.lock();
        try {
            //Business code, judgment, waiting, business, notification
            while (number!=2){
                condition2.await();
            }

            System.out.println(Thread.currentThread().getName()+"--------->"+number);
            number++;
            condition3.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void Test3(){
        lock.lock();
        try {
            //Business code, judgment, waiting, business, notification
            while (number!=3){
                condition3.await();
            }

            System.out.println(Thread.currentThread().getName()+"--------->"+number);
            number=1;
            condition.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}



6. Eight locks

  • 1. Under standard conditions, do two threads send text messages or call first? Answer: text first, then call

  • 2. sendMsg is delayed for 4 seconds. Do the two threads print and send text messages first or call? Answer: text first, then call

  • 3. After adding a common method, do you want to send text messages or hello? Answer: hello first, then send text messages

  • 4. Two exclusive and two synchronization methods. Do you send text messages or call first? Answer: call first, then send text messages

  • 5. Add two static synchronization methods. There is only one object. Do you send text messages first or call first? Answer: text first, then call

  • 6. Two static synchronization methods, two objects, send text messages first or call first? Answer: text first, then call

  • 7. A static synchronization method, an ordinary synchronization method, with only one object, send text messages first or call? Answer: call first, then send text messages

  • 8. A static synchronization method, a common synchronization method, two objects, send text messages first or call? Answer: call first, then send text messages

Summary:

  1. new objects, each object is a lock, and the lock is the object itself, this;
  2. Static static method. The locked Class is globally unique;
  3. For the same lock, whoever obtains the lock first will execute it first; Do not lock, according to the specific implementation of the CPU;
    ps: if there is something wrong, please comment and correct it and learn from each other.

Labels: lock objects

7. Unsafe assembly

List is not safe

ArrayList is not secure

resolvent

  • List list = new Vector<>(); (the bottom layer is synchronized)
  • List list = Collections.synchronizedList(new ArrayList<>());
  • List list= new CopyOnWriteArrayList(); (the bottom layer is Lock)
package com.wdzl.unsafe;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

//java. util. Concurrent modificationexception concurrent modification exception
public class ListTest {
    public static void main(String[] args) {
//        List<String> list = new ArrayList<>(); // Thread unsafe


        /**
         * Solution 1
         * 1.List<String> list = new Vector<>();
         */
        //List<String> list = new Vector<>();

        /**
         * Solution 2
         * 2. List<String> list = Collections.synchronizedList(new ArrayList<>());
         */
//        List<String> list = Collections.synchronizedList(new ArrayList<>());

        /**
         * Solution 3
         * 3. List<String> list= new CopyOnWriteArrayList();
         */
        List<String> list= new CopyOnWriteArrayList();


        for (int i=0;i<10;i++){
            new Thread(()->{
                list.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(list);
            },String.valueOf(i)).start();
        }

    }
}

Set is not safe

Solution
​ * 1.Set set = Collections.synchronizedSet(new HashSet<>());
​ * 2. Set set =new CopyOnWriteArraySet<>();

package com.wdzl.unsafe;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;

public class SetList {
    public static void main(String[] args) {
       // Set<String> set = new HashSet<>(); // unsafe
        /**
         * Solution
         * 1.Set<String> set = Collections.synchronizedSet(new HashSet<>());
         * 2. Set<String> set =new CopyOnWriteArraySet<>();
         */

//        Set<String> set = Collections.synchronizedSet(new HashSet<>());
        Set<String> set =new CopyOnWriteArraySet<>();
        for (int i=0;i<10;i++){
            new Thread(()->{
                set.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(set);
            },String.valueOf(i)).start();
        }
    }
}

HashSet bottom

The bottom layer of Hash is HashMap

 public HashSet() {        map = new HashMap<>();    }set add The value of is map of key Value, key The value cannot be repeated public boolean add(E e) {        return map.put(e, PRESENT)==null;    }

Map is not secure

important

New HashMap < > (16,0.75) initialCapacity = 16 (initial capacity), LoadFactor = 0.75 (load factor 0.75)

Solution
* 1.Map<String, String> map = Collections.synchronizedMap(new HashMap<>());
* 2. Map<String, String> map =new ConcurrentHashMap<>(); Concurrent HashMap

package com.wdzl.unsafe;import java.util.Collections;import java.util.HashMap;import java.util.Map;import java.util.UUID;import java.util.concurrent.ConcurrentHashMap;//New HashMap < > (16,0.75) initialCapacity = 16 (initial capacity), LoadFactor = 0.75 (load factor 0.75) public class maplist {public static void main (string [] args) {map < string, string > map = new HashMap < > (); / / thread unsafe / * * * solution * 1. Map < string, string > map = collections.synchronizedmap (New HashMap < > (); * 2. Map < string, string > map = new concurrenthashmap < > () ; Concurrent HashMap * / / / map < string, string > map = collections synchronizedMap(new HashMap<>());//         Map<String, String> map =new ConcurrentHashMap<>();       for (int i=0;i<10;i++){            new Thread(()->{                map.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0, 5));                System.out.println(map);            }, String. valueOf(i)). start();        }    }}

8.Callable

1. Return value

2. Exceptions can be thrown

3. The method is call ()

How to use Callable? Use the implementation class FutureTask of Runable

package com.wdzl.callable;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.FutureTask;public class CallableTest {    public static void main(String[] args) throws ExecutionException, InterruptedException {        //How to use Callable? Use the implementation class of Runable futuretask myThread myThread = new mythread(); FutureTask futureTask = new FutureTask(myThread);         new Thread(futureTask,"A"). start();         Object o = futureTask. get();         System. out. println(o);    }} Class myThread implements Callable < integer > {@ override public integer call() throws exception {system. Out. Println ("Zhao Dashuai coin...); return 1024;    }}

Details:

1. There is a cache (multiple threads call the same method, and the results are printed only once)

2. The result of get() may need to wait and block

9. Common auxiliary classes

9.1CountDownLatch (subtraction counter)

package com.wdzl.add;import java.util.concurrent.CountDownLatch;public class CountDownLatchDemo {    public static void main(String[] args) throws InterruptedException {        CountDownLatch countDownLatch=new CountDownLatch(6);        for (int i = 1; i <=6; i++) {            new Thread(()-> {                System.out.println(Thread.currentThread().getName()+"go out------>");                    countDownLatch.countDown();//Quantity minus one}, string valueOf(i)). start();        }         countDownLatch. await();// Wait for the counter to return to zero, and then execute system out. Println ("close the door...");}}

9.2cyclicbarrier (addition counter)

package com.wdzl.add;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;public class CyclicBarrierDemo {    public static void main(String[] args) {        //The number of counts is 7 cyclicbarrier cyclicbarrier = new cyclicbarrier (7, () - > {system. Out. Println ("summon Dragon...");}); For (int i = 1; I < = 7; I + +) {final int temp = I; new thread (() - > {system. Out. Println (thread. Currentthread(). Getname() + "get the first dragon ball."+ temp);                try {                    cyclicBarrier.await();                } catch (InterruptedException e) {                    e.printStackTrace();                } catch (BrokenBarrierException e) {                    e.printStackTrace();                }            }).start();        }    }}

9.3 semaphore (pass)

Function: multiple shared resources are mutually exclusive. Concurrent flow limiting to control the maximum number of threads

package com.wdzl.add;import java.util.concurrent.Semaphore;import java.util.concurrent.TimeUnit;public class SemaphoreDemo {    public static void main(String[] args) {        Semaphore semaphore = new Semaphore(3);//Number of threads that can be accommodated, Equivalent to parking space for (int i = 1; I < = 6; I + +) {new thread (() - > {try {semaphore. Acquire(); / / get thread System.out.println(Thread.currentThread().getName() + "get parking space --"); timeunit.seconds.sleep (2); System.out.println(Thread.currentThread().getName() + "leaving parking space --");} catch (InterruptedException e) {                    e.printStackTrace();                } Finally {semaphore. Release(); / / release thread}}, string valueOf(i)). start();        }    }}

10. Read write lockreadwritelock

Exclusive lock (write lock): it can only be occupied by one thread at a time

Shared lock (read lock): multiple threads can share it

package com.wdzl.readWriteLock;import java.util.HashMap;import java.util.Map;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;public class ReadWriteLockDemo {    public static void main(String[] args) {        MyCache myCache = new MyCache();        //Write lock for (int i = 1; I < 6; I + +) {final int temp = I; new thread (() - > {mycache.put (temp + "", temp + "");}, String. valueOf(i)). start();        }        // Read lock for (int i = 1; I < 6; I + +) {final int temp = I; new thread (() - > {mycache. Get (temp + "");}, String. valueOf(i)). start();        }    }}// Resource class, Custom cache class mycache {private volatile map < string, string > map = new HashMap < > (); readwritelock readwritelock = new reentrantreadwritelock(); / / save, write public void put (string key, string value) {readwritelock. Writelock(). Lock(); try {system. Out. Println (thread. Currentthread(). Getname() + "write" +key);            map.put(key, value);            System.out.println(Thread.currentThread().getName() + "write succeeded");} catch (Exception e) {            e.printStackTrace();        } finally {            readWriteLock.writeLock().unlock();        }    }    // Get and read public void get (string key) {readwritelock. Readlock(). Lock(); try {system.out.println (thread. Currentthread(). Getname() + "read" + key); map.get (key); system.out.println (thread. Currentthread(). Getname() + "write read succeeded");} catch (Exception e) {            e.printStackTrace();        } finally {            readWriteLock.readLock().unlock();        }    }}

11. Blocking queue

[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-bul1fkcd-1628393314067)(
)]

When to use blocking queues: multithreading, concurrent processing, thread pool

Relationship between blocking queue and set: same level as set and list

[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-zqzesqe4-1628393314070)(
)]

Learn to use queues

Add, remove

Four sets of API s

modeThrow exceptionIf there is a return value, no exception will be thrownWait for blocking (dead, etc.)Timeout wait (end after time)
add toadd()offer()put()offer(,)
removeremove()poll()take()poll(,)
Inspection team head elementelement()peek()--
package com.wdzl.bq;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.TimeUnit;public class BlockingQueueDemo {    public static void main(String[] args) throws InterruptedException {        BlockingQueueDemo blockingQueueDemo = new BlockingQueueDemo();//        blockingQueueDemo.test1();       // blockingQueueDemo.test2();        //blockingQueueDemo.test3();        blockingQueueDemo.test4();    }    /**     *  Throw an exception * / public void test1() {/ / queue size arrayblockingqueue BlockingQueue = new arrayblockingqueue < > (3); / / add system.out.println (BlockingQueue. Add ("a")); system.out.println (BlockingQueue. Add ("B")); system.out.println (BlockingQueue. Add ("C")); / / system.out.println (BlockingQueue. Add ("C"); / / system.out.println (blockingQueue.add("d"));//  Queue full throws an exception system out. println(blockingQueue.element());// View the queue head element / / remove system out. println(blockingQueue.remove());         System. out. println(blockingQueue.remove());         System. out. println(blockingQueue.remove());//        System. out. println(blockingQueue.remove());// Throw exception Java util. NoSuchElementException} / * * * no exception thrown * / public void test2() {/ / queue size arrayblockingqueue BlockingQueue = new arrayblockingqueue < > (3); / / add system.out.println (BlockingQueue. Offer ("a")); system.out.println (BlockingQueue. Offer ("B"); system.out.println (BlockingQueue. Offer( "c"));         System. out. println(blockingQueue.offer("d")); // Do not throw an exception. false / / view the first element system out. println(blockingQueue.peek());        // Remove system out. println(blockingQueue.poll());         System. out. println(blockingQueue.poll());         System. out. println(blockingQueue.poll());         System. out. println(blockingQueue.poll()); // Don't throw exception null} / * * * wait for blocking dead wait * * / public void test3() throws InterruptedException {/ / queue size arrayblockingqueue BlockingQueue = new arrayblockingqueue < > (3); / / add blockingqueue.put ("a"); blockingqueue.put ("B"); blockingqueue.put ("C") ;//         blockingQueue. put("d");        // Remove system out. println(blockingQueue.take());         System. out. println(blockingQueue.take());         System. out. println(blockingQueue.take());    }    /**     *  Timeout waiting * / public void test4() throws InterruptedException {/ / queue size arrayblockingqueue BlockingQueue = new arrayblockingqueue < > (3); / / add system.out.println (BlockingQueue. Offer ("a")); system.out.println (BlockingQueue. Offer ("B"); system.out.println (BlockingQueue. Offer ("C")) );         System. out. println(blockingQueue.offer("d",2, TimeUnit.SECONDS)); // Wait for two seconds and exit when there is no space. / / remove system out. println(blockingQueue.poll());         System. out. println(blockingQueue.poll());         System. out. println(blockingQueue.poll());         System. out. println(blockingQueue.poll(2,TimeUnit.SECONDS));// The timeout time is two seconds. If it exceeds, exit}}

12. Synchronization queue

  • Synchronization queue
  • Unlike other blockingqueues, synchronous queues do not store elements
  • If an element is put, you must take it from the inside, otherwise you cannot put the value
package com.wdzl.bq;import java.util.concurrent.BlockingQueue;import java.util.concurrent.SynchronousQueue;import java.util.concurrent.TimeUnit;/** * The synchronization queue * is different from other blockingqueues. The synchronization queue does not store elements * put an element. You must take it from the inside, otherwise you cannot put the value */public class SynchronousQueueDemo {    public static void main(String[] args) {        BlockingQueue blockingQueue=new SynchronousQueue();        new Thread(()->{            try {                System.out.println(Thread.currentThread().getName()+"--------"+" put1");                blockingQueue.put(1);                                System.out.println(Thread.currentThread().getName()+"--------"+"put2");                blockingQueue.put(2);                System.out.println(Thread.currentThread().getName()+"--------"+"put3");                blockingQueue.put(3);            } catch (InterruptedException e) {                e.printStackTrace();            }        },"A").start();        new Thread(()->{            try {                TimeUnit.SECONDS.sleep(3);                System.out.println(Thread.currentThread().getName()+"--------"+blockingQueue.take());                TimeUnit.SECONDS.sleep(3);                System.out.println(Thread.currentThread().getName()+"--------"+blockingQueue.take());                TimeUnit.SECONDS.sleep(3);                System.out.println(Thread.currentThread().getName()+"--------"+blockingQueue.take());            } catch (InterruptedException e) {                e.printStackTrace();            }        },"B").start();    }}

13. Thread pool

Thread pool: three methods, seven parameters and four rejection strategies

Benefits of thread pool:

1. Reduce resource consumption

2. Improve response speed

3. Convenient management

Three methods:

package com.wdzl.pool;import java.util.concurrent.Executor;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;// Executors, tool class, Three methods public class Demo1 {public static void main (string [] args) {executorservice executorservice = executors. Newsinglethreadexecutor(); / / single thread ExecutorService executorService1 = Executors.newFixedThreadPool(5) ;// Create a fixed thread pool size executorservice executorservice2 = executors newCachedThreadPool();// Scalable, generating the corresponding maximum number of threads according to the number of tasks try {for (int i = 0; I < 10; I + +) {final int temp = I; executorservice2. Execute (() - > {system. Out. Println (thread. Currentthread(). Getname() + "... >" + temp);});}} catch (Exception e) {            e.printStackTrace();        }  finally {            executorService.shutdown();        }    }}

Seven parameters:

  public ThreadPoolExecutor(      int corePoolSize,//Core thread pool size intmaximumPoolSize, / / maximum core thread pool size long keepAliveTime, / / timeout timeunit, / / timeout unit BlockingQueue < runnable > workqueue, / / blocked queue threadfactory, threadfactory, / / thread factory, blocked thread, Generally, RejectedExecutionHandler handler / / reject Policy) {this (corepoolsize, maximumpoolsize, keepalivetime, unit, workqueue, threadfactory, defaulthandler);}

Four rejection strategies:

new ThreadPoolExecutor.AbortPolicy() / / the bank is full and there are still people coming. Don't handle it
new ThreadPoolExecutor.CallerRunsPolicy() / / go back where you came from
new ThreadPoolExecutor.DiscardOldestPolicy() / / when the queue is full, try to compete with the earliest without throwing an exception
new ThreadPoolExecutor.DiscardPolicy() / / if the queue is full, the task will be lost and no exception will be thrown

package com.wdzl.pool;import java.util.concurrent.*;// Executors, tool class, Three methods public class Demo1 {public static void main (string [] args) {/ * * * three methods * / ExecutorService executorService = Executors.newSingleThreadExecutor(); / / single thread ExecutorService executorService1 = Executors.newFixedThreadPool(5) ;// Create a fixed thread pool size executorservice executorservice2 = executors newCachedThreadPool();// Scalable, generate the corresponding maximum number of threads according to the number of tasks / * * Custom thread pool * / executorservice ThreadPoolExecutor = new ThreadPoolExecutor (2, 5, 3, timeunit. Seconds, new linkedblockingqueue < > (3), executors defaultThreadFactory(),                new ThreadPoolExecutor. Abortpolicy() / / when the bank is full, there are still people coming. Don't handle it. / / new ThreadPoolExecutor Callerrunspolicy() / / go back where you came from / / new ThreadPoolExecutor Discardoldestpolicy() / / when the queue is full, try to compete with the oldest one without throwing an exception. / / new ThreadPoolExecutor Discardpolicy() / / when the queue is full, no exception will be thrown); try {            for (int i = 0; i < 10; i++) {                final int temp=i;                threadPoolExecutor.execute(()->{                    System.out.println(Thread.currentThread().getName()+"............>"+temp);                });            }        }  catch (Exception e) {            e.printStackTrace();        }  finally {            executorService.shutdown();        }    }}

Summary expansion

How to set the maximum size of the pool!

Understanding: IO intensive, CPU intensive: (tuning)

package com.kuang.pool;        import java.util.concurrent.*;public class Demo01 {    public static void main(String[] args) {// Custom thread pool! Work ThreadPoolExecutor. / / how to define the maximum thread. / / 1. CPU intensive. Several cores, that is, several cores, can maintain the highest CPU efficiency// 2. io intensive > double the number of io consuming threads in your program. / / the program has 15 large tasks, which io takes up a lot of resources// Get the number of cores of CPU system out. println(Runtime.getRuntime(). availableProcessors());                ExecutorService threadPool = new ThreadPoolExecutor(                2,                Runtime.getRuntime(). availableProcessors(),                3,                TimeUnit. SECONDS,                new LinkedBlockingDeque<>(3),                Executors. defaultThreadFactory(),                new ThreadPoolExecutor. DiscardOldestPolicy()); // If the queue is full, try to compete with the earliest, and no exceptions will be thrown! Try {/ / maximum load: Deque + max / / exceeds rejectedexecutionexception for (int i = 1; I < = 9; I + +) {/ / after using thread pool, use thread pool to create thread ThreadPool. Execute (() - > {system. Out. Println (thread. Currentthread(). Getname() + "OK");});}} catch (Exception e) {            e.printStackTrace();        }  Finally {/ / when the thread pool runs out, the program ends. Close threadPool.shutdown();}}}

14. Four functional interfaces

1. Functional interface: the interface with only one method

Function functional interface: it has an input parameter and a return value

package com.wdzl.function;import java.util.function.Function;/** * Function Functional interface with one input parameter and one output */public class Demo1 {    public static void main(String[] args) {       Function<String,String> function= new Function<String, String>() {            @Override            public String apply(String s) {                return s;            }        };       Function<String,String> function1=(String str)->{return str;};        System.out.println(function1.apply("wwwwwwwwww"));    }}

Assertive interface: there is an input parameter, and the return value can only be Boolean!

package com.wdzl.function;import java.util.function.Predicate;/** * Assertive interface: there is an input parameter, and the return value can only be Boolean! */public class Demo2 {    public static void main(String[] args) {// Judge whether the string is empty / / predict < string > predict = new predict < string > () {@ override public Boolean test (string STR) {return str.isempty();}}; Predicate<String> predicate = (str)->{return str.isEmpty(); };         System. out. println(predicate.test(""));    }}

Consumer consumer interface: only input, no return value

package com.wdzl.function;import java.util.function.Consumer;public class Demo3 {    public static void main(String[] args) {       Consumer<String> consumer= new Consumer<String>() {            @Override            public void accept(String o) {                System.out.println(o);            }        };        Consumer<String> consumer2=(str)->{            System.out.println(str);        };       consumer2.accept("22222222");    }}

Supplier supply type interface: no parameters, only return values

package com.wdzl.function;import java.util.function.Supplier;public class Demo4 {    public static void main(String[] args) {       Supplier<Integer> supplier= new Supplier<Integer>() {            @Override            public Integer get() {                return 1024;            }        };        System.out.println(supplier.get());    }}

15.Stream flow calculation

Big data: storage + computing

The essence of collection and MySQL is to store things;

Calculations should be left to the flow to operate!

package com.wdzl.steam;import java.util.Arrays;import java.util.List;/** * Title Requirements: complete this title in one minute, which can only be realized with one line of code* Now there are 5 users! Filtering: * 1. ID must be an even number * 2. Age must be older than 23 * 3. User name is changed to uppercase * 4. User name is sorted upside down * 5. Only one user is output! */public class Test {    public static void main(String[] args) {        User u1 = new User(1,"a",21);        User u2 = new User(2,"b",22);        User u3 = new User(3,"c",23);        User u4 = new User(4,"d",24);        User u5 = new User(6,"e",25);// The set is the storage list < user > List = arrays asList(u1, u2, u3, u4, u5);//  Give the calculation to the Stream / / lambda expression, chain programming, functional interface, Stream flow calculation list Stream()                . filter(u->{return u.getId()%2==0;})//                . filter(u->{return u.getAge()>23;})//                . map(u->{return u.getName().toUpperCase();})//                . sorted((uu1,uu2)->{return uu2.compareTo(uu1);})//                . limit(1)                . forEach(u->{                    System.out.println(u);                });    }}

16. Forkjoin (split and merge)

ForkJoin executes tasks in parallel in JDK 1.7! increase of efficiency. Large amount of data!

Big data: Map Reduce (splitting big tasks into small tasks)

[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-jx45wp1e-1628393314072)(
)]

ForkJoin features: job theft

[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-vyxufcgq-1628393314074)(
)]

Application class

package com.wdzl.forkjoin;import java.util.concurrent.RecursiveTask;/** * The task of summation calculation* 3000 6000 (ForkJoin) 9000 (Stream parallel Stream) * / / how to use forkjoin * // 1. Execute forkjoinPool through it * / / 2. Calculate the task forkjoinPool.execute(ForkJoinTask task) * // 3 The calculation class should inherit ForkJoinTask */public class ForkJoinDemo extends RecursiveTask<Long> {    private Long start; // 1    private Long end; // 1990900000 / / critical value private long temp = 10000l; public ForkJoinDemo(Long start, Long end) {        this.start = start;        this.end = end;    }    //  Calculation method @ override protected long compute() {if ((end start) < temp) {long sum = 0l; for (long I = start; I < = end; I + +) {sum + = I;} return sum;        } Else {/ / forkjoin recursive long middle = (start + end) / 2; / / intermediate value forkjoindemo Task1 = new forkjoindemo (start, middle); Task1. Fork(); / / split the task and push it into the thread queue forkjoindemo task2 = new forkjoindemo (middle + 1, end); task2. Fork()) ; //  Split the task and push the task into the thread queue return Task1 join() + task2. join();        }    }}

Test class

package com.wdzl.forkjoin;import java.util.concurrent.ExecutionException;import java.util.concurrent.ForkJoinPool;import java.util.concurrent.ForkJoinTask;import java.util.stream.LongStream;/** * For the same task, others are dozens of times more efficient than you! */public class Test {    public static void main(String[] args) throws ExecutionException {// test1(); // 12224// test2(); // 10038 test3(); // 153} / / ordinary programmer public static void test1() {long sum = 0l; long start = system. Currenttimemillis(); for (long I = 1L; I < = 10_0000_0000; I + +) {sum + = I;} long end = System. currentTimeMillis();         System. out. Println ("sum =" + sum + "time:" + (end start));}// Forkjoin public static void test2() throws executionexception will be used, Interruptedexception {long start = system. Currenttimemillis(); forkjoinpool forkjoinpool = new forkjoinpool(); forkjointask < long > task = new forkjoindemo (0l, 10_0000_0000l); forkjointask < long > submit = forkjoinpool. Submit (task); / / submit task long sum = submit. Get(); long end = system. Currenttimemillis() ;         System. out. Println ("sum =" + sum + "time:" + (end start));} Public static void test3() {long start = system. Currenttimemillis(); / / stream parallel stream () (] long sum = longstream.rangeclosed (0l, 10_0000_0000l). Parallel(). Reduce (0, long:: sum); long end = system. Currenttimemillis(); system.out.println ("sum =" + "time:" + (end start));}}

17. Asynchronous callback

The original intention of Future design: to model the result of an event in the Future

package com.wdzl.future;import java.util.concurrent.CompletableFuture;import java.util.concurrent.ExecutionException;/** * Asynchronous call: CompletableFuture * / / asynchronous execution * / / successful callback * / / failed callback */public class Demo01 {    public static void main(String[] args) throws ExecutionException,            InterruptedException {// Runasync asynchronous callback without return value / / completable future < void > completable future = completable future runAsync(() -> {// try {// TimeUnit.SECONDS.sleep(2);// } catch (InterruptedException e) {// e.printStackTrace();// }//            System. out. println(Thread.currentThread(). getName() + "runAsync=>Void");// });  System. out. println("1111");  completableFuture. get(); //  Obtain the blocking execution result. / / a supplyasync asynchronous callback with a return value. / / ajax, successful and failed callbacks. / / an error is returned// The error message is returned; CompletableFuture<Integer> completableFuture =                    CompletableFuture. supplyAsync(() -> {                        System.out.println(Thread.currentThread().getName() + "supplyAsync=>Integer");                        int i = 10 / 0;                        return 1024;                    });             System. out. Println (completable future. Whencomplete ((T, U) - > {system. Out. Println ("t = >" + T); / / normal return result system. Out. Println ("U = >" + U); / / error message: Java. Util. Concurrent. Completionexception: Java. Lang. arithmetexception: / by zero}) Exceptionally ((E) - > {system. Out. Println (e.getmessage()); return 233; / / you can get the wrong return result});});}}

18.JMM

JMM: Java Memory Model, nonexistent things, concepts! appointment!

Volatile is a lightweight synchronization mechanism provided by Java virtual machine

1. Ensure visibility

2. Atomicity is not guaranteed

3. Prohibit instruction rearrangement

Some synchronization conventions of JMM:

1. Before the thread is unlocked, the shared variable must be flushed back to main memory immediately.

2. Before locking a thread, you must read the latest value in main memory into working memory!

3. Locking and unlocking are the same lock

Thread working memory, main memory

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-lwqsjnyw-1628393314076)(
)]

There are 8 kinds of memory interactive operations. The virtual machine implementation must ensure that each operation is atomic and cannot be separated (for variables of double and long types, exceptions are allowed for load, store, read and write operations on some platforms)

lock: a variable that acts on main memory and identifies a variable as thread exclusive

unlock: a variable that acts on the main memory. It releases a locked variable, and the released variable can be locked by other threads

read: acts on the main memory variable. It transfers the value of a variable from the main memory to the working memory of the thread for subsequent load actions

load: a variable that acts on working memory. It puts the read operation from main memory into working memory

Use: acts on variables in working memory. It transfers variables in working memory to the execution engine. Whenever the virtual machine encounters a value that needs to be used, it will use this instruction

assign: acts on a variable in working memory. It puts a value received from the execution engine into the variable copy in working memory

store: a variable that acts on main memory. It transfers the value of a variable from working memory to main memory for subsequent write

write: acts on a variable in main memory. It puts the value of the variable obtained from the working memory by the store operation into the variable in main memory

JMM formulates the following rules for the use of these eight instructions:

One of read and load, store and write operations is not allowed to appear alone. That is, read must be loaded and store must be written

The thread is not allowed to discard its latest assign operation, that is, after the data of the work variable has changed, it must inform the main memory

A thread is not allowed to synchronize data without assign from working memory back to main memory

A new variable must be born in main memory. Working memory is not allowed to directly use an uninitialized variable. This means that the assign and load operations must be performed before the use and store operations are performed on the linked variables

Only one thread can lock a variable at a time. After multiple locks, you must perform the same number of unlocks to unlock

If you lock a variable, the value of this variable in all working memory will be cleared. Before the execution engine uses this variable, you must re load or assign to initialize the value of the variable

If a variable is not locked, it cannot be unlocked. You cannot unlock a variable that is locked by another thread

Before unlock ing a variable, you must synchronize the variable back to main memory

[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-0i9kcian-1628393314077)(
)]

19.Volatile

1. Ensure visibility

package com.wdzl.jmm;import java.util.concurrent.TimeUnit;public class JMMDemo {    //If you do not add volatile, the program will loop. / / adding volatile can ensure visibility. Private volatile static int num = 0; Public static void main (string [] args) {/ / mainthread new thread (() - > {while (Num = = 0) {}}) start();         try {            TimeUnit.SECONDS.sleep(1);        }  catch (InterruptedException e) {            e.printStackTrace();        }         num=1;         System. out. println(num);    }}

2. Atomicity is not guaranteed

Atomicity: indivisible

Thread A cannot be disturbed or divided when executing tasks. Either succeed or fail at the same time.

package com.wdzl.jmm;// Volatile does not guarantee atomicity public class vdemo02 {/ / volatile does not guarantee atomicity private volatile static int num = 0; public static void add() {num + +;} Public static void main (string [] args) {/ / theoretically, the num result should be 20000 for (int i = 1; I < = 20; I + +) {new thread (() - > {for (int j = 0; J < 1000; j + +) {add();}}) start();        }         while (Thread.activeCount() > 2) { // main gc            Thread.yield();        }         System. out. println(Thread.currentThread(). getName() + " " + num);    }}

How to ensure atomicity without lock and synchronized

Atomic classes can be used to solve atomicity

package com.wdzl.jmm;import java.util.concurrent.atomic.AtomicInteger;// Volatile does not guarantee atomicity public class vdemo02 {/ / volatile does not guarantee atomicity / / integer private static atomicinteger num = new atomicinteger(); public static void add() {/ / num + +; / / it is not an atomic operation num.getAndIncrement(); // AtomicInteger + 1 method, CAS} public static void main (string [] args) {/ / theoretically, the num result should be 20000 for (int i = 1; I < = 20; I + +) {new thread (() - > {for (int j = 0; J < 1000; j + +) {add();}}) start();        }         while (Thread.activeCount() > 2) { // main gc            Thread.yield();        }         System. out. println(Thread.currentThread(). getName() + " " + num);    }}

3. Instruction rearrangement

What is instruction rearrangement: the computer does not execute the program you write as you write.

Source code – > compiler optimized rearrangement – > instruction parallelism may also rearrange – > memory system may also rearrange - > execution

When the processor rearranges instructions, consider the dependency between data!

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-2Bf6S6N7-1628393314078)(D:\jvm image \ 2.png)]

[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-ekrmm4iu-1628393314079)(
)]

volatile avoids instruction rearrangement:

Memory barrier. CPU instructions.

effect:

1. Ensure the execution sequence of specific operations!

2. Memory visibility of some variables can be guaranteed (visibility is achieved by volatile using these features)

[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-wynw3ptz-1628393314079)(
)]

Volatile s can maintain visibility. Atomicity cannot be guaranteed. Due to the memory barrier, instruction rearrangement can be avoided!

20. Completely play with singleton mode

Singleton mode: a class has only one instance, and it is responsible for creating its own object. This class provides a way to access its unique object, which can be accessed directly without instantiating the object of this class.

Core code: construction method, privatization, private.

1. Hungry Han style

It's also easy to understand from the name, which is "relatively diligent". The instance has been built at the time of initialization. Whether you use it or not, you should build it first. The advantage is that there is no thread safety problem, and the disadvantage is a waste of memory space.

package com.wdzl.singal;/** * Hungry Han style */public class EHan {    private EHan(){}//Privatization construction method private static ehan instance = new ehan(); public static EHan getInstance(){        return instance;    }}

2. Lazy style

As the name suggests, an instance is created only when it is used. It is "lazy". When it is used, it is checked whether there is an instance. If there is an instance, it will be returned. If there is no instance, it will be created. There are two ways to write thread safe and thread unsafe. The difference is the synchronized keyword.

package com.wdzl.singal;/** * Lazy style */public class LHan {    private LHan(){}//Privatization construction method private static LHAn instance; public static LHan getInstance(){        if (instance==null){            instance=new LHan();        }         return instance;    }}

3. Double check lock

Double check lock, also known as double check lock, integrates the advantages and disadvantages of lazy type and hungry type. In the above code implementation, the feature is that a layer of if condition judgment is added inside and outside the synchronized keyword, which not only ensures thread safety, but also improves execution efficiency and saves memory space compared with direct locking.

package com.wdzl.singal;public class DoubleCheck {    private DoubleCheck(){}//Privatization construction method private static doublecheck instance; public static DoubleCheck getInstance(){        if (instance==null){            synchronized (DoubleCheck.class){                if (instance==null){                    instance=new DoubleCheck();                }            }        }         return instance;    }}

4. Static internal class

The effect of static internal class is similar to double check lock, but the implementation is simpler. However, this method is only applicable to the static domain. The double check lock method can be used when the instance domain needs to delay initialization.

package com.wdzl.singal;public class Singleton {    private static class SingletonHolder{        private static final Singleton InSTANCE=new Singleton();    }    private Singleton(){}    public static final Singleton getInstance(){        return SingletonHolder.InSTANCE;    }}

5. Enumeration

Enumeration is a rare implementation, but the code implementation above is more concise and clear. It also automatically supports the serialization mechanism to absolutely prevent multiple instantiations.

package com.wdzl.singal;public enum  Signletion {    INSTANCE;    public void anyMethod(){    }}

21. In depth understanding of CAS

CAS purpose

Use the CAS instruction of CPU and JNI to complete the non blocking algorithm of Java. Other atomic operations are performed using similar characteristics. The whole J.U.C is built on CAS, so J.U.C has greatly improved the performance of synchronized blocking algorithm.

CAS is used for synchronization by reading the value A from address V, performing multi-step calculation to obtain the new value B, and then using CAS to change the value of V from A to B. If the value at V has not been changed at the same time, the CAS operation is successful.

package com.wdzl.cas;import java.util.concurrent.atomic.AtomicInteger;public class CASDemo {    // CAS compareAndSet: compare and exchange! Public static void main (string [] args) {atomicinteger atomicinteger = new atomicinteger (2020); / / expect and update / / public final boolean compareAndSet(int expect, int update) / / if the expected value is reached, update it. Otherwise, do not update it. CAS is the concurrency primitive of CPU! System.out.println (atomicinteger. Compareandset) (2020, 2021));         System. out. println(atomicInteger.get());//         atomicInteger. getAndIncrement();         System. out. println(atomicInteger.compareAndSet(2020, 2021));         System. out. println(atomicInteger.get());    }}

Problems in CAS

1.ABA problem. CAS needs to check whether the value has changed when operating the value. If it has not changed, it will be updated. However, if a value turns out to be a, becomes B, and then becomes a, it will be found that its value has not changed when using CAS for inspection, but actually has changed. The solution to ABA problem is to use version number. Add the version number in front of the variable. Add one version number each time the variable is updated, and A-B-A will become 1A-2B-3A.

2. Long cycle time and high overhead. If spin CAS fails for a long time, it will bring very large execution overhead to the CPU. If the JVM can support the pause instruction provided by the processor, the efficiency will be improved. The pause instruction has two functions, First, it can delay the pipeline execution instructions so that the CPU will not consume too much execution resources. The delay time depends on the specific implementation version, and the delay time is zero on some processors. Second, it can avoid emptying the CPU pipeline due to memory order violation when exiting the loop (CPU pipeline flush), so as to improve the execution efficiency of the CPU.

3. Only atomic operation of one shared variable can be guaranteed. When operating on a shared variable, we can use cyclic CAS to ensure atomic operation. However, when operating on multiple shared variables, cyclic CAS cannot ensure the atomicity of the operation. At this time, we can use locks or a clever way is to combine multiple shared variables into one shared variable. For example, there are two shared variables i = 2 and j = A. merge ij=2a, and then use CAS to operate ij. From Java 1 Since 5, JDK has provided AtomicReference class to ensure atomicity between reference objects. You can put multiple variables in one object for CAS operation.

21. Atomic reference

package com.wdzl.cas;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicStampedReference;public class CASDemo2 {    //AtomicStampedReference: if the generic type is a wrapper class, pay attention to the object reference. / / normal business operations are performed, and objects are compared. Static AtomicStampedReference < integer > AtomicStampedReference = new AtomicStampedReference < > (1, 1)// CAS compareandset: compare and exchange! Public static void main (string [] args) {new thread (() - > {int stamp = AtomicStampedReference. Getstamp(); / / get the version number system.out.println ("A1 = >" + stamp); try {timeunit.seconds.sleep (1);} catch (InterruptedException e) {                e.printStackTrace();            }             AtomicStampedReference. compareAndSet(1, 2,                    AtomicStampedReference.getStamp(),                    AtomicStampedReference. getStamp() + 1);             System. out. println("a2=>" + AtomicStampedReference.getStamp());             System. out. println(AtomicStampedReference.compareAndSet(2, 1,                    AtomicStampedReference.getStamp(),                    AtomicStampedReference. getStamp() + 1));             System. out. println("a3=>" + AtomicStampedReference.getStamp());        },  "a"). start();//  The principle of optimistic lock is the same! New thread (() - > {int stamp = AtomicStampedReference. Getstamp(); / / get the version number system.out.println ("B1 = >" + stamp); try {timeunit.seconds.sleep (2);} catch (InterruptedException e) {                e.printStackTrace();            }             System. out. println(AtomicStampedReference.compareAndSet(1, 6,                    stamp, stamp + 1));             System. out. println("b2=>" + AtomicStampedReference.getStamp());        },  "b"). start();    }}

be careful:

Integer uses the object caching mechanism. The default range is - 128 ~ 127. It is recommended to use the static factory method valueOf to obtain object instances instead of new, because valueOf uses caching, and new will create new objects and allocate new memory space;

22. Understanding of various locks

1. Fair lock, unfair lock

Fair lock: very fair. You can't jump the queue. You must come first!

Unfair lock: very unfair. You can jump in the queue (all unfair by default)

2. Reentrant lock

Reentrant lock (recursive lock)

Synchronized

package com.wdzl.lock;import java.util.concurrent.TimeUnit;// Synchronizedpublic class Demo01 {    public static void main(String[] args) {        Phone phone = new Phone();        new Thread(()->{            phone.sms();        }, "A"). start();         new Thread(()->{            phone.sms();        }, "B"). start();    }} class Phone{    public synchronized void sms(){        System.out.println(Thread.currentThread().getName() + "sms");        try {            TimeUnit.SECONDS.sleep(2);        }  catch (InterruptedException e) {            e.printStackTrace();        }         call(); //  There is also a lock} public synchronized void call() {system. Out. Println (thread. Currentthread(). Getname() + "call");}}

lock

package com.wdzl.lock;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class Demo02 {    public static void main(String[] args) {        Phone2 phone = new Phone2();        new Thread(()->{            phone.sms();        },"A").start();        new Thread(()->{            phone.sms();        },"B").start();    }}class Phone2{    Lock lock = new ReentrantLock();    public void sms(){        lock.lock(); // Details: lock lock();  lock. unlock(); //  Lock locks must be paired, or they will die inside lock lock();         Try {system. Out. Println (thread. Currentthread(). Getname() + "SMS"); / / there is also a lock} catch (exception E) {e.printstacktrace();} finally {            lock.unlock();            lock.unlock();        }    }     public void call(){        lock.lock();        try {            System.out.println(Thread.currentThread().getName() + "call");        }  catch (Exception e) {            e.printStackTrace();        }  finally {            lock.unlock();        }    }}

3. Spin lock

package com.wdzl.lock;import java.util.concurrent.TimeUnit;public class TestSpinlock {    public static void main(String[] args) throws InterruptedException {// ReentrantLock reentrantLock = new ReentrantLock();// reentrantLock.lock();// reentrantLock.unlock();//  Spin lock CAS spinlockdemo used in the bottom layer lock = new spinlockdemo(); new Thread(()-> {            lock.myLock();            try {                TimeUnit.SECONDS.sleep(5);            }  catch (Exception e) {                e.printStackTrace();            }  finally {                lock.myUnLock();            }        }, "T1"). start();         TimeUnit. SECONDS. sleep(1);         new Thread(()-> {            lock.myLock();            try {                TimeUnit.SECONDS.sleep(1);            }  catch (Exception e) {                e.printStackTrace();            }  finally {                lock.myUnLock();            }        }, "T2"). start();    }}

4. Deadlock

[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-qkmol58h-1628393314080)(
)]

package com.wdzl.lock;import java.util.concurrent.TimeUnit;public class DeadLock {    public static void main(String[] args) {        String lockA = "lockA";        String lockB = "lockB";        new Thread(new MyThread(lockA, lockB), "T1").start();        new Thread(new MyThread(lockB, lockA), "T2").start();    }}class MyThread implements Runnable {    private String lockA;    private String lockB;    public MyThread(String lockA, String lockB) {        this.lockA = lockA;        this.lockB = lockB;    }    @Override    public void run() {        synchronized (lockA) {            System.out.println(Thread.currentThread().getName() +                    "lock:" + lockA + "=>get" + lockB);            try {                TimeUnit.SECONDS.sleep(2);            } catch (InterruptedException e) {                e.printStackTrace();            }            synchronized (lockB) {                System.out.println(Thread.currentThread().getName() +                        "lock:" + lockB + "=>get" + lockA);            }        }    }}

solve the problem

[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-lcnd4pc-1628393314081)(
)]

Interview, at work! Troubleshooting:

1. Log 9

2. Stack 1

Topics: Java