目录
1.概述
2.Thread的常见构造方法
3.Thread的几个常见属性
4.启动一个线程-start()
5.中断一个线程
5.1通过共享的标记来进行沟通
5.2 调用 interrupt() 方法来通知
6.等待一个进程
7.获取当前线程引用
8.线程的状态
8.1所有状态
8.2线程状态和转移的意义
1.概述
Thread是jvm用来管理线程的一个类,即,在Java中,每个线程都有一个唯一的Thread对象与之关联。
每个执行流,也需要有一个对象来描述,类似下图所示,而 Thread 类的对象
就是用来描述一个线程执行流的,JVM 会将这些 Thread 对象组织起来,用于线程调度,线程管理
2.Thread的常见构造方法
方法 | 说明 |
Thread() | 创建线程对象 |
Thread(Runnable target) | 使用 Runnable 对象创建线程对象 |
Thread(String name) | 创建线程对象,并命名 |
Thread(Runnable target, String name) | 使用 Runnable 对象创建线程对象,并命名 |
3.Thread的几个常见属性
属性 | 获取方法 |
ID | getId() |
名称 | getName() |
状态 | getState() |
优先级 | getPriority() |
是否后台线程 | isDaemon() |
是否存活 | isAlive() |
是否被中断 | isInterrupted() |
4.启动一个线程-start()
之前我们已经看到了如何通过覆写 run 方法创建一个线程对象,但线程对象被创建出来并不意味着线程就开始运行了。
覆写 run 方法是提供给线程要做的事情的指令清单线程对象可以认为是把 李四、王五叫过来了
而调用 start() 方法,就是喊一声:”行动起来!“,线程才真正独立去执行了。
调用 start 方法, 才真的在操作系统的底层创建出一个线程.即,run方法是一个行动指南,而真正让这个线程创建并执行出来的,是strat()方法。
5.中断一个线程
对于正在run方法中执行的线程,我们一般有两种方法来中断;
5.1通过共享的标记来进行沟通
public class demo3 {public static boolean quit;public static void main(String[] args) throws InterruptedException {Thread t = new Thread(()->{while (!quit){System.out.println("线程在执行...");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t.start();Thread.sleep(5000);System.out.println("结束线程");quit=true;}
}
5.2 调用 interrupt() 方法来通知
public class demo3 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(()->{while (!Thread.currentThread().isInterrupted()){System.out.println("线程在执行...");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t.start();Thread.sleep(5000);System.out.println("结束线程");t.interrupt();}
}
1. 如果线程因为调用 wait/join/sleep 等方法而阻塞挂起,则以 InterruptedException 异常的形式通
知,清除中断标志,当出现 InterruptedException 的时候, 要不要结束线程取决于 catch 中代码的写法. 可以选择忽略这个异常, 也可以跳出循环结束线程.
2.否则,只是内部的一个中断标志被设置,t可以通过Thread.interrupted() 判断当前线程的中断标志被设置,清除中断标志Thread.currentThread().isInterrupted() 判断指定线程的中断标志被设置,不清除中断标志这种方式通知收到的更及时,即使线程正在 sleep 也可以马上收到。
6.等待一个进程
有时,我们需要等待一个线程完成它的工作后,才能进行自己的下一步工作。这时我们需要一个方法明确等待线程的结束
方法 | 说明 |
public void join() | 等待线程结束 |
public void join(long millis) | 等待线程结束,最多等 millis 毫秒 |
public void join(long millis, int nanos) | 同理,但可以更高精度 |
import java.util.Random;public class demo1 {public static int tmp1;public static int tmp2;public static void main(String[] args) throws InterruptedException {int[] array = new int[10000000];Random random = new Random();for (int i = 0; i < array.length; i++) {int n = random.nextInt(100);array[i] = n;}long time1 = System.currentTimeMillis();Thread t1 = new Thread(()->{for (int i = 0; i < array.length; i+=2) {tmp1+=array[i];}});Thread t2 = new Thread(() ->{for (int i = 1; i < array.length; i+=2) {tmp2+=array[i];}});t1.start();t2.start();t1.join();t2.join();System.out.println("数组中的随机数总和="+(tmp1+tmp2));long time2 = System.currentTimeMillis();System.out.println("程序运行时间=" + (time2-time1)+"ms" );}
}
如果把这两个join注释的话:
7.获取当前线程引用
方法 | 说明 |
public static Thread currentThread(); | 返回当前线程对象的引用 |
public static void main(String[] args) {Thread t = Thread.currentThread();System.out.println(t.getName());}