Multithreading study notes 1- basics

Multithreading Basics

1. Thread name

Thread has a default name, beginning with Thread-, start counting from 0.

2. Thread the runnable instance, if there is no transmission. The same can be run.

3. Thread Group

If the time to create a thread, do not specify the use of a ThreadGroup ThreadGroup parent thread. Both threads in the same ThreadGroup.

4. StackSize

  1. This is the constructor parameters Thread, expressed this thread stack size that can be used, instead of using the default JVM size distribution. If this parameter is not specified, it defaults to 0, which means ignore this parameter, which will be JNI calls.
  2. This parameter take effect in some platforms, some platforms will not take effect.

5. Daemon

When the end of the parent thread, this thread will end, and will not hang in the background it has been executed. Daemon execution must be placed after the start, otherwise an error exception.

6. Join

Only for the thread after the join, have to wait until the join thread execution is completed, in order to perform the following. clothes moth timeOut join may be provided, join represents how long, over this period of time, then the code to perform the following. join must be placed after the start, to take effect; however, it will not start before placing an error.

7. Interrupt

When calling Interrupt method, the use of sleep, wait, join these methods in the thread, causes the thread to throw an interrupt exception, close the thread. interrupt is interrupt join that thread.

8. Close a Thread (Grace For Close Thread)

  1. The original jdk in using stop method to close a thread, then close the thread because this method will produce a series of problems. Therefore, this method is no longer recommended.
  2. Solution:
    1. Volatile modified a boolean value, while monitoring the use of this thread, and when launch the program. Use of the reasons volatile. Because, Common properties are present in a respective separate copy of each thread, the modification does not affect the other thread paste. The Volatile thread is mandatory to update the data, other threads need to re-load the data. Ensure the accuracy of the data.
public class ThreadInterruptDemo {

    private static class Worker extends Thread {
        private volatile boolean is_Down = false;

        @Override
        public void run() {
            while (is_Down) {
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        public void shutDown() {
            this.is_Down = true;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Worker worker = new Worker();

        worker.start();

        Thread.sleep(10_000);

        worker.shutDown();
    }
}
  1. Use interrupt (Interrupt) mechanism to exit the thread: Call Interrupt method thread, and then, in the method call sleep the thread again, join, wait approach may lead to interruption thread throws an exception, leading to quit thread.
public class ThreadInterruptDemo2 {

    private static class Worker extends Thread {

        @Override
        public void run() {
            while (true) {
                if (Thread.interrupted()) { // 若中断, 则退出线程.
                    return;
                }

                System.out.println("ing.........");
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Worker worker = new Worker();

        worker.start();

        Thread.sleep(3_000);

        worker.interrupt();
    }
}

9. forced to close a thread (Force close Thread)

Stop method is not recommended. And you can use daemon threads, the main thread is closed, leading to withdraw daemon threads to perform tasks.

public class ThreadService {

    private Thread executeThread;

    private boolean finished = false;

    public void execute(Runnable task) {        executeThread = new Thread(() -> {
            Thread runner = new Thread(task); //真正执行任务的线程.
            runner.setDaemon(true); // 设置为守护线程, 则只需要主线程退出, 守护线程也就退出了.
            runner.start();

            try {                runner.join(); // 拦截代码往下面执行.等待任务执行完成.
                finished = true;
            } catch (InterruptedException e) {                System.out.println("触发中断异常");
            }        });

        executeThread.start();
    }
    /**
     * 外部其它线程, 调用此方法关闭executeThread,
     * 从而保证了可以强制关闭runner(执行任务线程)的关闭.
     * @param  maxSpendTime: 此任务最大可以消耗的时间, 超时则关闭此任务.
     */
    public void shutDown(long maxSpendTime) {        long currentTimeMillis = System.currentTimeMillis();
        while (!finished) {            long endTime = System.currentTimeMillis();
            if ((endTime - currentTimeMillis) >= maxSpendTime) {                System.out.println("此任务超时....");
                executeThread.interrupt(); //使用了join, 产生中断异常.
                break;
            }
            try {
                executeThread.sleep(1);
            } catch (InterruptedException e) {                System.out.println("执行线程被中断");
                break;
            }        }

        finished = false;
    }}



public class CloseThreadMain {

    public static void main(String[] args) {
        ThreadService service = new ThreadService();
        long currentTimeMillis = System.currentTimeMillis();
        service.execute(() -> {            // 执行一个长时间任务.
            while (true) { // 触发中断异常

            }
            /*try { // 正常任务执行结束.
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }*/
        });

        service.shutDown(10000); //制定超过多少时间, 关闭此线程.
        long endTime = System.currentTimeMillis();
        System.out.println(endTime - currentTimeMillis);  // 得到线程花费时间.
}}

Guess you like

Origin blog.csdn.net/weixin_38608626/article/details/93380862