Java并发编程之常用方法

118 阅读3分钟

常用方法

  • currentThread():静态方法,获取当前线程
Thread.currentThread();
  • start():开启线程
Thread thread = new Thread();
thread.start();
  • run():线程执行方法,创建线程时重写此方法
public class MyThread extends Thread {
    @Overrided
    public void run() {
        System.out.println("线程正在执行");
    }
}
  • setName():设置线程名称,必须在调用start方法之前设置
Thread thread = new Thread();
thread.setName("线程1");
thread.start();
  • join():等待该线程执行完
public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            try {
                Thread.sleep(1000);
                System.out.println("t1 线程正在执行...");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        t1.start();
        t1.join();     // 等t1线程执行完才会继续向下执行
        System.out.println("main 线程继续执行...");
    }
  • join(timeout):限时等待该线程,如果时间到了或者该线程提前执行完了,就会继续向下执行。
    t1.join(1000); // 等待t1线程1秒,然后继续执行
  • setPriority():设置线程优先级,1-10,默认5,但是设置了优先级不代表一定会按照优先级顺序执行,在任务较多的情况下,优先级高的线程可能会执行的次数较多,具体执行还要看CPU的调度情况
Thread thread = new Thread();
thread.setPriority(8);
  • isAlive():线程是否存活
Thread thread = new Thread();
thread.start();
System.out.println(thread.isAlive());
  • interrupt():打断线程,线程调用了sleep/wait/join等能够响应中断的方法(会抛出InterruptedException异常)时,调用interrupt方法会打断线程
public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            try {
                Thread.sleep(1000);
                System.out.println("t1 线程正在执行...");
            } catch (InterruptedException e) {
                System.out.println("t1被打断...");
            }
        });
        t1.start();
        t1.interrupt();// 打断t1线程
    }
  • isInterrupted():查看线程是否被打断,不会影响线程的中断状态
t1.isInterrupted();
  • interrupted():静态方法,查看线程是否被打断,会清除线程的中断状态
Thread.interrupted();
  • sleep(timeout):让当前线程睡眠一定时间,并且不会让出CPU的执行权,时间到了或者被打断才会继续执行
Thread.sleep(1000);// 当前线程睡眠一秒
  • yield():让出CPU执行权,但是会重新竞争CPU的执行权(你运行吧你运行吧,刚让出去又抢回来),基本不用这个了
Thread t1 = new Thread();
t1.yield();

场景应用

  1. 多个线程t1t2t3顺序执行

t1线程中调用t2.join(),在t2线程中调用t3.join(),就可以实现t3执行完了再执行t2t2执行完了再执行t1

  1. 循环中防止CPU占用过高

通过sleep(0)能够让出CPU的执行权重新竞争资源,防止一直占用CPU

while(true) {
 Thread.sleep(0);
 // 业务代码
}
  1. 两阶段终止模式优雅终止线程
public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            while (true) {                                        // 1
                if (Thread.currentThread().isInterrupted()) {     // 2
                    break;
                }
                try {
                    Thread.sleep(1000);
                    System.out.println("t1 线程正在执行...");      // 3
                } catch (InterruptedException e) {
                    System.out.println("t1线程被打断...");
                    Thread.currentThread().interrupt();           // 4
                }
            }
        });
        t1.start();
        Thread.sleep(3000);
        t1.interrupt();                                           // 5
    }
  • 1处循环表示t1线程不停地在执行任务
  • 2处获取线程是否中断来判断是否要跳出循环,结束任务
  • 3处是线程执行的业务代码
  • 4处重新调用interrupt方法是因为捕获InterruptedException后会清除中断状态标志,也就是说isInterrupted()方法获取的值是false,所以重新调用一遍interrupt方法把中断状态标志重新设置为true,下次循环就能跳出。
  • 5处在主线程打断t1线程