多线程并发总结--线程生命周期以及状态

多线程是一个经常接触的东西,之前在使用的时候没有做过系统的总结和梳理,最近根据自己的想法,把自己之前做过的看过的都总结一遍。最终转化为自己的东西,进一步提升自己。直接切入主题,生命周期状态。

生命状态图

线程生命周期状态.jpg

对于线程在各个方法各个环节的总结,网上的资料都已经很多很多了,我这里就不打算在进行总结了。只是记录自己在最近的项目中对线程生命周期的一些想法进行总结梳理。

如何结束一个线程

最近在项目中,经常使用一直循环运行的子线程,为了控制好线程的运行以及结束。最常用的方法就是设置共享控制变量。通过修改控制变量跳出子线程中的循环代码,结束 run 方法中的代码,从而完成线程的结束。之前结束线程官方的 api 还有一些结束的方法。最终都不推荐使用,后边会稍微的探究一下。官网解释:https://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html

修改共享变量方法

需要注意的两点(使用其中一种就可以)
1、使用关键词 volatile
2、变量的访问必须同步 synchronized

         //通常是两种做法
         //方法一:
         mThread = new Thread(() -> {

            while (true) {

                if (isExit) {
                    return;
                }

                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                count++;
                Log.d("qhh_thread", ">>> " + count + ", isExit " + isExit);

            }

        });

        //方法二:
        mThread.start();

         mThread = new Thread(() -> {

            while (!isExit) {

                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                count++;
                Log.d("qhh_thread", ">>> " + count + ", isExit " + isExit);

            }

        });
        mThread.start();

通过 interrupt 终止线程

在这里会有个问题,interrupt 其实只是修改了线程的状态,所以他不能直接停止线程的执行。
判断线程状态所使用的是 isInterrupt 方法。配合循环里面的return方法来终止线程的执行。

public class Main {

    private static long startTime;

    public static void main(String[] args) {

        Thread thread = new Thread(new MyRunnable());
        thread.start();

    }

    static class MyRunnable implements Runnable {

        @Override
        public void run() {

            startTime = System.currentTimeMillis();

            while (true) {

                boolean interrupted = Thread.currentThread().isInterrupted();

                if (interrupted) {
                    System.out.println(">>> interrupted is true");
                    return;
                }

                long currentTime = System.currentTimeMillis();
                if(currentTime - startTime >= 10000){
                    Thread.currentThread().interrupt();
                }

            }

        }
    }
}

因此可以看到 interrupt 只是修改了中断状态。线程在因为以下原因 Blocked 的时候,就可以通过 interrupt 结束进程。

  1. 如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个InterruptedException异常。这个时候,我们可以通过捕获InterruptedException异常来终止线程的执行,具体可以通过return等退出或改变共享变量的值使其退出。
  2. 如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个 ClosedByInterruptException。这时候处理方法一样,只是捕获的异常不一样而已。(这里需要注意的是不同的系统平台出现的异常不一样,Linux出现的是 InterruptException ,Windows则不会出现这种异常)

你可能感兴趣的:(多线程并发总结--线程生命周期以及状态)