一、线程sleep

1.sleep方法介绍

休眠有一个非常重要的特性,那就是其不会放弃monitor锁的所有权。

2.使用TimeUnit替代Thread.sleep

      在JDK1.5以后,引入了一个枚举TimeUnit,其对sleep方法提供了很好的封装,可以省略很多时间单位换算的步骤。看例子:

//Thread.sleep(10000L);
TimeUnit.HOURS.sleep(3);
TimeUnit.MINUTES.sleep(24);
TimeUnit.SECONDS.sleep(17);
TimeUnit.MILLISECONDS.sleep(88);
//此处列举出各种用法,简洁明了

二、线程yield

1.yield方法介绍

        yield方法属于一个启发式的方法,其会提醒调度器我愿意放弃当前的CPU资源,如果CPU资源不紧张,则会忽略这种提醒。调用yield方法会使当前线程从RUNNING状态切换到RUNNABLE状态。

注:yield只是一个提示,CPU调度器并不会担保每次都能满足yield提示。

2.yield和sleep

  • sleep会导致当前线程暂停指定的时间,并没有CPU时间片的消耗
  • yield只是对CPU调度器的一个提示,如果CPU调度器没有忽略这个提示,它会导致线程上下文的切换。
  • sleep会使线程短暂block,会在给定的时间内释放CPU资源
  • yield会使RUNNING状态的Thread进入RUNNABLE状态(如果CPU调度器没有忽略这个提示的话)。
  • sleep几乎百分之百的完成了给定时间的休眠,而yield的提示并不能一定担保。
  • 一个线程sleep另一个线程调用interrupt会捕获到中断信号,而yield

三、设置线程的优先级

1.进程和线程一样有优先级,理论上是优先级比较高的线程会获取优先被CPU调度的机会,但是事实上往往不会如你所愿,设置线程的优先级同样也是一个提醒(hint)操作。

2.线程的优先级不能小于1也不能大于10,如果指定的线程优先级大于线程所在group的优先级,那么指定的优先级将会失效,取而代之的是group的最大优先级。

四、获取线程ID

在一个JVM进程启动的时候,实际上是开辟了很多个线程,自增序列已经有了一定的消耗。

五、获取当前线程

        public static Thread currentThread() 用于返回当前执行线程的引用。

六、设置线程上下文类加载器

  • public ClassLoader getContextClassLoader()
  • public void setContextClassLoader(ClassLoader cl) 这个方法可以打破JAVA类加载器的父委托机制,也被称为JAVA类加载器的后门。

七、线程interrupt

1.interrupt

调用当前线程的interrupt方法,就可以打断阻塞。

2.isInterrupted

        isInterrupted主要判断当前线程是否被中断,仅仅只是对interrupt标示的一个判断。

3.interrupted

判断当前线程是否被中断,但是该方法会擦除掉线程的interrupt标识,如果当前线程被打断,第一次调用interrupted方法会返回true,立即擦除标识,第二次包括以后的调用永远都返回false,除非在此期间线程又一次地被打断。

八、线程join

        Thread的join方法是一个非常重要的方法,与sleep一样也是一个可中断的方法。

join某个线程A,会使当前线程B进入等待,直到线程A结束生命周期,或者到达给定的时间,那么在此期间B线程是处于BLOCKED的,而不是A线程。

      【join方法比较重要,之后会单独更新一篇join方法的实战应用代码案例】

九、如何关闭一个线程

1.线程结束生命周期正常结束

2.捕获中断信号关闭线程(interrupt标识)

3.使用volatile开关控制

使用volatile修饰的开关flag关闭线程也是一种常用的做法。volatile开关控制,示例代码

static  class  MyTask extends Thread {
        
        private volatile boolean closed = false;

        @Override
        public void run() {
            System.out.println("I will start work.");
            while(!closed && !isInterrupted()) {
                //执行
            }
            System.out.println("I will be exiting.");
        }
}

异常退出、进程假死的情况。

篇外:jvisualvm工具说明

        jvisualvm工具是用来监控线程,内存情况,查看方法的CPU时间和内存中的对象,已被GC的对象,反向查看分配的堆栈的一个工具,在jdk包中已有提供,进入jdk/bin目录下,找到jvisualvm可执行文件使用命令行执行即可弹出可视化界面。除此之外还有jstack、jconsole等工具,都在这个目录。

        工具的启动路径可以配置到IntelliJ IDEA中,方便使用,具体方式可以自行百度。

        附上此工具的操作界面图。

pod java线程数 java线程api_pod java线程数