Thread 类是 JVM 用来管理线程的一个类,换句话说,每个线程都有一个唯一的 Thread 对象与之关联。 要想知道Thread类的基本用法,首先得知道如何创建Thread类,创建Thread类的方法大抵有多种,这里简单的举例比较常用的。
1)继承Thread类,然后像创建普通类一样创建Thread类。
2)实现 Runnable 接口,创建 Thread 类实例, 调用 Thread 的构造方法时将 Runnable 对象作为 target 参数.
3)匿名内部类创建 Thread 子类对象
4)匿名内部类创建 Runnable 子类对象
5)lambda 表达式创建 Runnable 子类对象
class Student extends Thread{ @Override public void run() { System.out.println("haha1"); } } class Teacher implements Runnable{ @Override public void run() { System.out.println("haha2"); } } public class Test2 { public static void main(String[] args) { Student student = new Student();//方法1 student.start(); Thread thread2 = new Thread(new Teacher());//方法2 thread2.start(); Thread thread3 = new Thread(){ @Override public void run() { System.out.println("haha3"); } };//方法3 thread3.start(); Thread thread4 = new Thread(new Runnable() { @Override public void run() { System.out.println("haha4"); } });//方法4 thread4.start(); Thread thread5 = new Thread(() -> { System.out.println("haha5"); });//方法5 thread5.start(); } }
当知道Thread类被创建后,就得知道如何使用Thread类了,首先得知道,start()方法,start()被调用才能创建线程,我们重写的方法run()只是将要被线程执行的逻辑罢了,其次则是Thread的构造方法,从上面的如何创建Thread类,就可以了解到几个Thread的构造方法,首先是典型的没有任何参数的构造方法,方法一和方法三就是,然后则是使用 Runnable 对象创建线程对象 ,方法二,四,五就是(Thread(Runnable target)),当然还有给线程命名的构造方法,毕竟没有给线程命名的话,这调用和调试起来也不太方便(Thread类的对象名不是线程名)(Thread(String name)),最后则是使用 Runnable 对象创建线程对象并且顺便给线程命名的构造方法(Runnable target, String name),这里只说四个并不只有四个,只是其他方法运用较少,这里不做讨论。
然后则是Thread的常见属性了,Thread的属性较多,这里只做几个较为重要的属性认识。
1)ID:ID 是线程的唯一标识,不同线程不会重复,其获取方法为通过Thread类的对象来获取。
Thread thread6 = new Thread(() -> { System.out.println("hehe"); }); thread6.getId();
2)名称:名称是各种调试工具用到,其可以为自己通过创建Thread对象时给的名称name(Thread(String name)),也可以是不给名称由系统默认取名。获取方法为:
thread6.getName();
3)状态:则是线程当前处于的状态,是已完成,还是已创建但没有启动,亦或者是已启动但还没完成的状态等。获取方法则为:
thread6.getState();
4)优先级:事情有轻重缓急,进程也一样,理论上优先级高的线程更容易被调度。获取方法为:
thread6.getPriority();
5)是否为后台线程:关于后台线程,需要记住一点:JVM会在一个进程的所有非后台线程结束后,才会结束运行。获取方法为:
thread6.isDaemon();
6)是否存活:run 方法是否运行结束了,获取方法为:
thread6.isAlive();
7)是否被中断:线程的中断问题,下面我们进一步说明,获取方法为:
thread6.isInterrupted();
关于中断线程,若一个线程已经启动起来了,该怎样让它停下来呢?
public static int n = 3; public static void main(String[] args) { Thread thread = new Thread(() -> { while (n != 0){ ; } System.out.println("haha"); }); thread.start(); n = 0; }
其次则是2,使用 Thread.interrupted() 或者 Thread.currentThread().isInterrupted() 代替自定义标志位.其Thread.currentThread()表示获取当前的线程,isInterrupted()则可以认为是Thread对象内部提供了一个标志位(bonlean),而isInterrupted()则是获取当前标志位,默认为false,倘若要修改标志位的话,只需要使用Interrupted()方法。
public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(() -> { while (!Thread.currentThread().isInterrupted()){ System.out.println("haha"); } }); thread.start(); sleep(1000); thread.interrupt(); }
因此,这里出现的方法也得熟练掌握。
thread.join(); thread.join(1000);