• 基础线程机制


    Executor

    Executor 管理多个异步任务的执⾏,⽽⽆需程序员显式地管理线程的⽣命周期。这⾥的异步是指多个任 务的执⾏互不⼲扰,不需要进⾏同步操作。

    主要有三种 Executor:

    CachedThreadPool:⼀个任务创建⼀个线程;

    FixedThreadPool:所有任务只能使⽤固定⼤⼩的线程;

    SingleThreadExecutor:相当于⼤⼩为 1 的 FixedThreadPool

    Daemon

    守护线程是程序运⾏时在后台提供服务的线程,不属于程序中不可或缺的部分。

     当所有⾮守护线程结束时,程序也就终⽌,同时会杀死所有守护线程。 main() 属于⾮守护线程。 在线程启动之前使⽤ setDaemon() ⽅法可以将⼀个线程设置为守护线程。

    sleep()

    Thread.sleep(millisec) ⽅法会休眠当前正在执⾏的线程,millisec 单位为毫秒。 sleep() 可能会抛出 InterruptedException,因为异常不能跨线程传播回 main() 中,因此必须在本地进⾏ 处理。

    线程中抛出的其它异常也同样需要在本地进⾏处理。

    public void run() {
     try {
     Thread.sleep(3000);
     } catch (InterruptedException e) {
     e.printStackTrace();
     }
    }

    yield()

    对静态⽅法 Thread.yield() 的调⽤声明了当前线程已经完成了⽣命周期中最重要的部分,可以切换给其 它线程来执⾏。

    该⽅法只是对线程调度器的⼀个建议,⽽且也只是建议具有相同优先级的其它线程可以 运⾏。

    中断

    ⼀个线程执⾏完毕之后会⾃动结束,如果在运⾏过程中发⽣异常也会提前结束

    InterruptedException

    通过调⽤⼀个线程的 interrupt() 来中断该线程,如果该线程处于阻塞、限期等待或者⽆限期等待状态, 那么就会抛出 InterruptedException,从⽽提前结束该线程。

    但是不能中断 I/O 阻塞和 synchronized 锁 阻塞。 对于以下代码,在 main() 中启动⼀个线程之后再中断它,由于线程中调⽤了 Thread.sleep() ⽅法,因此 会抛出⼀个 InterruptedException,

    从⽽提前结束线程,不执⾏之后的语句。

    public class InterruptExample {
     private static class MyThread1 extends Thread {
     @Override
     public void run() {
     try {
     Thread.sleep(2000);
     System.out.println("Thread run");
     } catch (InterruptedException e) {
     e.printStackTrace();
     }
     }
     }
    }
    public static void main(String[] args) throws InterruptedException {
     Thread thread1 = new MyThread1();
     thread1.start();
     thread1.interrupt();
     System.out.println("Main run");
    }

    Main run java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at InterruptExample.lambda$main$0(InterruptExample.java:5) at InterruptExample$$Lambda$1/713338599.run(Unknown Source) at java.lang.Thread.run(Thread.java:745)

    interrupted()

    如果⼀个线程的 run() ⽅法执⾏⼀个⽆限循环,并且没有执⾏ sleep() 等会抛出 InterruptedException 的 操作,那么调⽤线程的 interrupt() ⽅法就⽆法使线程提前结束。

     但是调⽤ interrupt() ⽅法会设置线程的中断标记,此时调⽤ interrupted() ⽅法会返回 true。因此可以在 循环体中使⽤ interrupted() ⽅法来判断线程是否处于中断状态,从⽽提前结束线程。

    public class InterruptExample {
     private static class MyThread2 extends Thread {
     @Override
     public void run() {
     while (!interrupted()) {
     // ..
     }
     System.out.println("Thread end");
     }
     }
    }
    public static void main(String[] args) throws InterruptedException {
     Thread thread2 = new MyThread2();
     thread2.start();
     thread2.interrupt();
    }
    Thread end


    如果只想中断 Executor 中的⼀个线程,可以通过使⽤ submit() ⽅法来提交⼀个线程,它会返回⼀个 Future 对象,通过调⽤该对象的 cancel(true) ⽅法就可以中断线程

    
    
  • 相关阅读:
    使用递归遍历目录
    Isseck 定位文件流
    二:C标准库文件I/O函数
    IPC进程通信
    操作系统知识总结
    Makefile简单使用
    人际交往
    AIX ksh补全命令
    java.lang.IllegalArgumentException: Wildcard string cannot be null or empty.
    WEB项目实现QQ在线推广功能
  • 原文地址:https://www.cnblogs.com/tingtin/p/15926214.html
Copyright © 2020-2023  润新知