Java Concurrent Programming (02): thread core mechanism, basic concept extension

Source code of this article: GitHub · click here | gitee · click here

1、 Thread basic mechanism

1. Concept description

The characteristic of concurrent programming is that the program can be divided into multiple separate and independent tasks, and these independent tasks can be driven by threads, so as to improve the overall efficiency. A basic demonstration case is provided below.

2. Application case

Scenario: suppose there is a container set. You need to take out each element in the container for processing. Generally, it is good to traverse directly. If the data is too large, you can cut the set according to the number of threads, and each thread processes part of the data, so the processing time will be greatly reduced.

public class ExtendThread01 {
    public static void main(String[] args) {
        List<Object> dataList = new ArrayList<>() ;
        dataList.add("A");
        dataList.add("B");
        dataList.add("C");
        // 把一个大的集合按照每个子集合的2个元素切割
        List<List<Object>> splitList = splitList(dataList,2);
        for (List<Object> list:splitList){
            System.out.println(list);
        }
        // 多线程处理
        for (List<Object> childList:splitList){
            ListTask listTask = new ListTask(childList) ;
            Thread runThread = new Thread(listTask);
            runThread.start();
        }
    }
    /**
     * List 集合切割
     */
    private static List<List<Object>> splitList (List<Object> list,int childSize) {
        if (list == null || list.size() == 0 || childSize < 1) {
            return null;
        }
        List<List<Object>> result = new ArrayList<>();
        int size = list.size();
        int count = (size + childSize - 1) / childSize ;
        for (int i = 0; i < count; i++) {
            List<Object> subList = list.subList(i * childSize,((i + 1) * childSize > size ? size : childSize * (i + 1)));
            result.add(subList);
        }
        return result;
    }
}
class ListTask implements Runnable {
    private List<Object> list ;
    public ListTask (List<Object> list){this.list=list;}
    @Override
    public void run() {
        for (Object object:list){
            System.out.println(Thread.currentThread().getName()+"=="+object);
        }
    }
}

Note: the case here is only the implementation of the scenario principle. This operation is not allowed in development. Thread pool processing is required, as will be described later. If the collection is not well controlled, a large number of thread threads will be created, resulting in memory overflow.

2、 Thread stop start

1. Basic process

The method of executing a task after the thread is started. In the process of execution, it can be blocked, dormant, awakened, stopped and a series of state operations.

Thread sleep function: when a thread enters the sleep (blocking) state after the execution of some tasks, the thread scheduler can switch to another thread, which is relatively fair to the execution of distributed tasks.

2. Use case

public class ExtendThread02 {
    public static void main(String[] args) {
        StopThread stopThread = new StopThread() ;
        stopThread.start();
        // 标记当前线程停止信号,且抛出中断异常,但没有停止
        stopThread.interrupt();
        // 判断当前线程是否已经是终止状态
        System.out.println("1=="+stopThread.isInterrupted());
        // 清除当前线程的终止信号
        System.out.println("2=="+stopThread.interrupted());
        // 再次判断当前线程状态
        System.out.println("3=="+stopThread.isInterrupted());
        System.out.println("main end ...");
    }
}
class StopThread extends Thread {
    @Override
    public void run() {
        for (int i = 0 ; i < 10 ; i++){
            try {
                System.out.println(Thread.currentThread().getId()+"="+i);
                // 线程阻塞1秒
                Thread.sleep(1000);
            } catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }
}

3. Core method

Sleep (long millis): the thread sleeps for the specified time and enters the blocking state;

Interrupt(): switch the thread to the interrupt state, throw an interrupt exception, and the thread will not be stopped. You can monitor the interrupt state of the thread and define the execution strategy.

Interrupted(): clearing the interrupt status of the thread calling this method will not affect the execution of the thread, and return the current execution 'stopthread Whether the thread of interrupted() 'is interrupted, which means whether the main thread is interrupted.

Isinterrupted(): judge whether the thread calling this method is in interrupted state.

Make up a sentence: these methods of threads are extremely confusing. You need to track the source code of breakpoints, enter the source code methods, and call the relevant APIs to check the status. (a breakpoint diagram is attached:)

3、 Thread priority

1. Basic concepts

The order of CPU execution and processing threads is uncertain, but the thread scheduler tends to execute threads with high thread priority. A high thread priority indicates a high probability of obtaining CPU resources, or the obtained execution time is fragmented, but it does not mean that the threads with low priority must be executed finally.

2. Use case

public class ExtendThread03 {
    public static void main(String[] args) {
        Priority01 priority01 = new Priority01();
        priority01.start();
        System.out.println("priority01="+priority01.getPriority());
        Priority02 priority02 = new Priority02();
        priority02.start();
        System.out.println("priority02="+priority02.getPriority());
        priority01.setPriority(10);
        priority02.setPriority(1);
    }
}
class Priority01 extends Thread {
    @Override
    public void run() {
        for (int i = 0 ; i < 100 ; i++){
            System.out.println(Thread.currentThread().getName()+";i="+i);
        }
    }
}
class Priority02 extends Thread {
    @Override
    public void run() {
        for (int a = 0 ; a < 100 ; a++){
            System.out.println(Thread.currentThread().getName()+";a="+a);
        }
    }
}

Note: if the priority range [max_priority = 10, min_priority = 1] exceeds the range, an illegalargumentexception will be thrown.

Suggestion: generally, in actual development, it is not allowed to easily modify the parameters of thread operation, which is easy to cause exceptions beyond cognition.

4、 Thread join

1. Basic concepts

If thread a executes the join method of thread B, thread a will wait for thread B to finish executing and then return to continue executing.

2. Use case

public class ExtendThread04 {
    public static void main(String[] args) {
        JoinThreadA joinThreadA = new JoinThreadA() ;
        joinThreadA.start();
    }
}
class JoinThreadA extends Thread {
    @Override
    public void run() {
        System.out.println("缺水中...");
        JoinThreadB joinThreadB = new JoinThreadB() ;
        joinThreadB.start();
        try{
            joinThreadB.join();
        } catch (Exception e){
            e.printStackTrace();
        }
        System.out.println("喝水中...");
    }
}
class JoinThreadB extends Thread {
    @Override
    public void run() {
        System.out.println("买水中...");
        try{
            TimeUnit.SECONDS.sleep(2);
        } catch (Exception e){
            e.printStackTrace();
        }
        System.out.println("买到水...");
    }
}

Note: you can set the join (long) time of the thread. After all, you can't wait for snow, moon and flowers. Life has time difference, so you can only meet later.

5、 Local thread

1. Basic concepts

Local thread variables, and the stored value of threadlocalmap maintained at the bottom layer:

static class Entry extends WeakReference<ThreadLocal<?>> {
    Object value;
    Entry(ThreadLocal<?> k,Object v) {
        super(k);
        value = v;
    }
}

That is, data is stored as key value pairs. If you are familiar with the source code of the collection container, this entry is a sense of deja vu.

2. Use case

public class ExtendThread05 {
    private static final ThreadLocal<Long> threadLocal = new ThreadLocal<>() ;
    private static void initBegin (){
        threadLocal.set(System.currentTimeMillis());
    }
    private static Long overTime (){
        return System.currentTimeMillis()-threadLocal.get();
    }
    public static void main(String[] args) throws Exception {
        ExtendThread05.initBegin();
        TimeUnit.SECONDS.sleep(3);
        System.out.println(ExtendThread05.overTime());
    }
}

ThreadLocal provides the ability of a thread to store variables in memory and is bound to the current thread. The value corresponding to the current thread can be obtained and set through the get and set methods. This is a common application in web development.

6、 Daemon thread

1. Basic concepts

Daemon threads support auxiliary threads and mainly play a scheduling and supporting role in the program. When all non daemon threads in the JVM end, the daemon thread will also end.

2. Use case

public class ExtendThread06 {
    public static void main(String[] args) throws Exception {
        InputStreamReader is = new InputStreamReader(system.in);
        BufferedReader br = new BufferedReader(is);
        String value = br.readLine();
        CheckThread checkThread = new CheckThread(value) ;
        checkThread.setDaemon(true);
        checkThread.start();
        System.out.println("Main End ...");
    }
}
class CheckThread extends Thread {
    private String spell ;
    public CheckThread (String spell){
        this.spell = spell ;
    }
    @Override
    public void run() {
        if (spell.startsWith("cs")){
            System.out.println(spell+":输入正确");
        } else {
            System.out.println(spell+":输入错误");
        }
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}

Note: the daemon thread needs to explicitly call setdaemon (true); Method, here you can see that the main thread ends and the integration program ends, regardless of the daemon thread in sleep. If you interrupt the sleep of non daemon threads, will you throw an exception on your face?

7、 Thread exception handling

1. Mechanism description

According to the exception handling mechanism in Java, throwing exceptions is reduced step by step. The task method run of the thread does not throw exceptions. Naturally, the rewritten or implemented methods cannot throw exceptions directly. It is recommended to catch exceptions in multithreading, and a targeted processing mechanism can be used.

2. Use case

public class ExtendThread07 {
    public static void main(String[] args) {
        TryThread tryThread = new TryThread();
        tryThread.setName("try-name");
        // 定义运行中异常处理策略
        MyExe myExe = new MyExe() ;
        tryThread.setUncaughtExceptionHandler(myExe);
        tryThread.start();
    }
}
class TryThread extends Thread {
    @Override
    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e){
            e.printStackTrace();
        }
        // 如何处理这里异常?
        Integer.parseInt("cicada") ;
    }
}
class MyExe implements Thread.UncaughtExceptionHandler {
    @Override
    public void uncaughtException(Thread t,Throwable e) {
        System.out.println(t.getName()+";异常:"+e.getMessage());
    }
}

By implementing the uncaughtexceptionhandler interface, and the thread needs to specify a custom exception handling object, it can also handle unchecked exceptions.

8、 Source code address

GitHub·地址
https://github.com/cicadasmile/java-base-parent
GitEE·地址
https://gitee.com/cicadasmile/java-base-parent
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>