Thread类的基本用法详解——JavaWeb
创始人
2025-05-29 21:22:14
0

目录

一、Thread类的介绍

1、定义

2、构造方法

3、常见属性

二、线程创建

1、继承Thread类

2、实现Runnable接口

3、匿名内部类

(1)、匿名内部类创建Thread子类对象

(2)、匿名内部类创建Runnable子类对象

4、使用lambda表达式

注:

三、线程中断

1、手动设置标志位

2、调用 interrupt() 方法

四、线程等待

五、线程休眠

六、获取当前线程实例


一、Thread类的介绍

1、定义

Thread类是JVM 用来管理线程的一个类,每个线程都有一个唯一的 Thread 对象与之关联。每个执行流,都需要有一个对象来描述,而 Thread 类的对象就是用来描述线程执行流的,JVM 会将这些 Thread 对象组织起来,用于线程调度,线程管理。

2、构造方法

方法说明举例
Thread()

创建线程对象

Thread t1 = new Thread();
 
Thread(Runnable target)使用Runnable对象创建线程对象Thread t2 = new Thread(new MyRunnable());
 
Thread(String name)创建线程对象,并命名Thread t3 = new Thread("线程1");
 
Thread(Runnable target,String name)使用Runnable对象创建线程对象,并命名Thread t4 = new Thread(new MyRunnable(), "线程2");
 
Thread(ThreadGroup group,Runnable target)线程可以被用来分组管理,分好的组即为线程组\

3、常见属性

属性获取方法说明

ID

getId()ID 是线程的唯一标识,不同线程不会重复
名称getName()名称是各种调试工具用到的
状态getState()状态表示线程当前所处的一个情况
优先级getPriority()优先级高的线程理论上来说更容易被调度到
是否后台线程isDaemon()JVM会在一个进程的所有非后台线程结束后才会结束运行。
是否存活isAlive() run 方法是否运行结束。
是否中断isInterrupted()\

二、线程创建

1、继承Thread类

  • 自定义一个类继承Thread类,并在该类中重写run方法。
  • 实例化该类,调用start()方法,创建线程。
class MyThread extends Thread{@Overridepublic void run(){while (true){System.out.println("线程1");}}
}
public class Demo01 {public static void main(String[] args) {MyThread t=new MyThread();t.start();}
}

 

2、实现Runnable接口

  • 自定义一个类实现Runnable接口,并在类中实现抽象方法run()。
  • 创建实该类后再将实例化对象作为参数传递到Thread类的构造器中,实例化Thread类的对象,通过Thread类的对象调用start()来创建线程。
class MyRunnable implements Runnable{@Overridepublic void run(){while (true){System.out.println("线程2");}}
}
public class Demo02 {public static void main(String[] args) {MyRunnable runnable=new MyRunnable();Thread t=new Thread(runnable);t.start();}
}

 

注:相比于继承 Thread 类,可以直接使用 this 表示当前线程对象的引用。实现 Runnable 接口,this 表示的是 MyRunnable 的引用,需要使用 Thread.currentThread()。

3、匿名内部类

(1)、匿名内部类创建Thread子类对象

  • 创建匿名内部类
  • 调用start方法创建线程
public class Demo03 {public static void main(String[] args) {Thread t=new Thread(){@Overridepublic void run(){while (true){System.out.println("线程3");}};t.start();while (true){System.out.println("main方法");}}
}

 

 (2)、匿名内部类创建Runnable子类对象

  • 创建匿名内部类
  • 调用start()方法创建线程
public class demo04 {public static void main(String[] args) {Thread t=new Thread(new Runnable() {@Overridepublic void run() {while (true){System.out.println("线程4");}}});t.start();while (true){System.out.println("main方法");}}
}

 

4、使用lambda表达式

public class Demo05 {public static void main(String[] args) {Thread t=new Thread(()->{while (true){System.out.println("线程5");}});t.start();while (true){System.out.println("main方法");}}
}

 

注:

      上面我们通过覆写 run 方法创建一个线程对象,但线程对象被创建出来并不意味着线程就开始运行了。覆写 run 方法是提供给线程要做的事情的指令清单,run不会创建新的线程,其是在main线程中执行的。调用 start 方法, 才真的在操作系统的底层创建出一个线程。

三、线程中断

1、手动设置标志位

使用自定义的变量来作为标志位。

public class demo01 {public static boolean isQuit=false;public static void main(String[] args) {Thread t=new Thread(()->{while (!isQuit){System.out.println("hello 线程1");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("线程1终止");});t.start();try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}//修改isQuit=true;}
}

 

 注:当把isQuit从成员变量改成局部变量时无法正常发挥作用。Java要求变量捕获,捕获的变量必须是final或“实际final”。

2、调用 interrupt() 方法

Thread内部包含一个boolean类型的变量作为线程是否被中断的标记。

可以使用Thread.interrupted()或Thread.currentThread().isInterrupted()代替自定义标志位。

方法说明
public void interrupt()中断对象关联的线程,如果线程正在阻塞,则以异常方式通知,
否则设置标志位
public static boolean interrupted()判断当前线程的中断标志位是否设置,调用后清除标志位
public boolean isInterrupted()

判断对象关联的线程的标志位是否设置,调用后不清除标志位

例:

public class demo02 {public static void main(String[] args) {Thread t=new Thread(()->{//currentThread是获取到当前线程实例(t)//isInterrupted是t对象里自带的一个标志位while (!Thread.currentThread().isInterrupted()){System.out.println("hello 线程2");try {Thread.sleep(1000);} catch (InterruptedException e) {try {Thread.sleep(2000);} catch (InterruptedException ex) {throw new RuntimeException(ex);}break;}}});t.start();try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}//将t内部的标志设置成truet.interrupt();}
}

 

interrupt()方法的作用:

  • 设置标志位为true
  • 如果该线程正在阻塞(sleep/join/wait)中,此时会将阻塞状态唤醒并通过抛出异常的方式让sleep立即结束。当sleep被唤醒时,sleep会自动把isInterrupted标志位给清空(true->false),这就导致下次循环仍然可以继续执行。可以在catch语句中增加break来结束循环。

四、线程等待

线程之间是并发执行的,操作系统对于线程的调度是无序的,无法判断两个线程的执行先后顺序。有些时候,我们需要能控制线程之间的顺序,线程等待就是其中一种控制线程执行顺序的手段,此处的等待主要是控制线程结束的先后顺序。

方法说明
public void join()等待线程结束
public void join(long millis)等待线程结束,最多等 millis 毫秒
public void join(long millis, int nanos)同理,但可以更高精度
public class demo03 {public static void main(String[] args) throws InterruptedException {Thread t=new Thread(()->{System.out.println("hello 线程3");});t.start();//在main方法中等待t执行完后再执行main方法t.join();System.out.println("hello main");}
}

 

        上图中我们通过在main方法中调用join()方法让main线程阻塞从而使“线程3”先执行,直到“线程3”执行完毕后main线程才从阻塞中解除继续执行。因此想让哪个线程阻塞,就要在哪个线程里调用join()方法。但当main线程调用join()方法时“线程3”已经结束,此时不再阻塞会立即往下执行。

join()方法分类:

  • 无参join()方法:“死等”直到程序结束。
  • 有参join()方法:指定最大超时时间,如果达到时间上限就不再等待。

五、线程休眠

当代码中的某个线程调用sleep()方法时,这个线程就从就绪队列移至阻塞队列暂时不参与调度等待sleep()时间结束,而当到达sleep()的时间则又会被调度到就绪队列。

方法说明
public static void sleep(long millis) throws InterruptedException休眠当前线程 millis毫秒
public static void sleep(long millis, int nanos) throws
InterruptedException
可以更高精度的休眠
public class Demo06 {public static void main(String[] args){Thread t=new Thread(()->{while (true){System.out.println("线程6");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t.start();}
}

注:因为线程的调度是不可控的,所以sleep()方法只能保证实际休眠时间大于等于参数设置的休眠时间的。

六、获取当前线程实例

可以通过Thread.currentThread()的方式来调用,返回的是线程对象的引用,有时候也可以用this替代。

相关内容

热门资讯

香港:《稳定币条例》将于202... 6月6日,香港特别行政区政府于宪报刊登《稳定币条例(生效日期)公告》,指定2025年8月1日为《稳定...
10年来我国新制定设区的市地方... 新华社北京6月6日电(记者范思翔)记者近日从全国人大常委会法工委了解到,目前我国享有设区的市地方立法...
自贸港政策加速三亚外向型经济集... 中新社三亚6月6日电 (张月和)“我们企业去年6月底在三亚中央商务区注册成立,实现了当年落地、当年投...
利亚德:诉讼程序因法院审理流程... 证券之星消息,利亚德(300296)06月06日在投资者关系平台上答复投资者关心的问题。 投资者提问...
《赴山海》排播失约,网友投诉退... 6月5日,“《赴山海》排播失约网友要求退款”的话题冲上热搜。据扬子晚报报道,多名消费者发起投诉认为视...
宁波建工子公司因被拖欠款项提起... 财中社6月6日电宁波建工(601789)发布公告,公司控股子公司温州宁建投资有限公司因温州东部新城投...
快手被执行3300万元,与爱奇... 6月4日,江苏省南通市中级人民法院发布两则执行公告,将北京快手科技有限公司列为被执行人,被执行金额分...
出实招!阳江公共法律服务惠民强... 为以法治之力护航阳江高质量发展,阳江市司法局以建设“覆盖城乡、便捷高效、均等普惠”的现代公共法律服务...
康美药业:公司依据法律相关规定... 证券之星消息,康美药业(600518)06月06日在投资者关系平台上答复投资者关心的问题。 投资者提...
索辰科技:政策方面公司无法预判 证券之星消息,索辰科技(688507)06月06日在投资者关系平台上答复投资者关心的问题。 投资者提...