Thread的基本用法

首先什么是Thread呢?Thread是创建和管理线程的核心类,下面我将对线程的创建、中断、等待、休眠以及如果获取线程实例做出解释说明

start的介绍

在创建线程之前我们得先要了解一个东西,什么是start?

1.启动线程,调用start()方法实际上是Java虚拟机(JVM)中为该线程分配必要的系统资源

2.调用线程的执行体,start()方法内部会自动调用线程的 run() 方法,这是线程实际执行任务的地方。你无需手动调用 run() 方法,直接调用 start() 方法即可。

线程创建

 下面我将介绍两种简单的线程创建方法

继承Thread类

最直接的方法当然是创建一个新的类,并重写其 run() 方法。在 run() 方法中定义线程需要执行的代码。然后创建该类实例并调用start()方法来启动线程

class MyThread extends Thread{
    public void run(){
        //线程执行的代码
        System.out.println(1);
    }
}
public class demo8 {
    public static void main(String[] args) {
         MyThread t = new MyThread();//创建线程实例
         t.start();//启动线程
    }
}

实现Runnable接口

创建一个类实现Runnable接口,并实现 run() 方法。然后将该类的实例传递给Thread类的构造函数,创建Thread对象,通过调用这个对象的start()方法来启动线程。(如果这里没懂后面代码中还有解释)

class MyRunnable implements Runnable{
    public void run(){
        System.out.println(1);
    }
}
public class demo8 {
    public static void main(String[] args) {
         MyRunnable myRunnable = new MyRunnable();//实例化Runnable
         Thread t = new Thread(myRunnable);//在Thread类的构造函数中,有一个重载形式
         //接受Runnable参数,当你创建Thread对象时,将你的Runnable实现类的实例作为参数
         //传递进去,这样做实际上是告诉新线程要执行的任务是什么
         t.start();
    }
}

线程中断

线程中断是Java中一种协作式的线程停止机制,它允许一个线程向另一个线程发出请求,要求被请求的线程停止当前工作。注意:这个机制并不直接停止线程的执行,而是设置一个中断标志,线程需要主动检查并响应这个中断标志

下面这段代码则是简单的演示了线程中断:

// 创建一个名为Worker的Runnable任务
        Runnable worker = new Runnable() {
            @Override
            public void run() {
                try {
                    for (int i = 0; i < 10; i++) {
                        // 模拟执行任务
                        System.out.println("正在执行任务, 迭代次数: " + i);
                        Thread.sleep(1000); // 模拟耗时操作,且该操作可被中断
                        // 检查中断状态,如果被请求中断,则退出循环
                        if (Thread.currentThread().isInterrupted()) {
                            System.out.println("检测到中断信号,退出循环。");
                            throw new InterruptedException("中断异常");
                        }
                    }
                } catch (InterruptedException e) {
                    // 捕获中断异常,打印信息并重新设置中断状态
                    System.out.println("线程被中断:" + e.getMessage());
                    Thread.currentThread().interrupt(); // 重新设置中断标志
                }
                System.out.println("Worker线程结束");
            }
        };

        Thread thread = new Thread(worker, "WorkerThread");
        thread.start(); // 启动线程

        try {
            // 让主线程等待一段时间后中断worker线程
            Thread.sleep(5000); // 主线程等待5秒
            System.out.println("主线程请求中断Worker线程");
            thread.interrupt(); // 发出中断请求
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

这段代码首先定义了一个实现了Runnable接口的匿名类,代表一个工作线程的任务。工作线程在运行时会每隔一秒打印一次迭代计数,并模拟耗时操作通过Thread.sleep(1000)。在循环中,它会检查当前线程是否被中断(通过Thread.currentThread().isInterrupted()),如果被中断,则抛出并捕获InterruptedException,同时重新设置中断标志,以便其他地方也能检查到中断状态。

主线程则启动这个工作线程,并在等待5秒后向工作线程发出中断请求。这样,你可以观察到工作线程响应中断并提前结束循环的整个过程。


结合上述代码我们来总结一下:

  1. 如何中断一个线程,可以调用线程对象的interrupt()方法
  2. 阻塞方法:如果线程在执行Thread.sleep(), Object.wait(), Thread.join()等可中断的阻塞方法时被中断,这些方法会抛出InterruptedException,这时线程可以捕获这个异常并据此做出响应。

  3. 周期性检查:在循环或长时间运行的任务中,应该定期检查Thread.currentThread().isInterrupted(),如果返回true,则表明线程被请求中断,此时线程应该清理资源并尽快结束执行。

  4. 重置中断状态

    当捕获到InterruptedException时,需要注意,JVM会自动清除中断状态。如果希望其他地方也能检测到中断请求,应该在catch块中重新设置中断状态,比如以下代码:

try {
    // 可能抛出InterruptedException的代码
    Thread.sleep(1000);
} catch (InterruptedException e) {
    Thread.currentThread().interrupt(); // 重新设置中断标志
    // 处理中断
}

线程等待

join

  • 作用:当前线程等待指定线程终止,可以设置等待时间。如果超过了指定的毫秒数,当前线程将不再等待。
  • 参数millis - 等待的时间(以毫秒为单位)。
  • 使用场景:当一个线程必须等待另一个线程执行完成才能继续执行时使用。
  • 异常:可能抛出InterruptedException

示例代码:

        Thread t = new Thread(()->{
            for (int i = 0; i < 5; i++) {
                System.out.println("t线程执行中...");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        System.out.println("t线程开始执行");
        t.start();
        t.join();//主线程等待t线程执行完
        System.out.println("t线程执行完毕");

wait

  • 作用:使当前线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法,或者超过指定的等待时间。
  • 使用场景:通常与synchronized一起使用,用于线程间的同步。
  • 参数:无参数版本将一直等待,也可以传入毫秒和纳秒参数指定最长等待时间。
  • 异常:可能抛出InterruptedException

示例代码:

        final Object lock = new Object();
        Thread t = new Thread(()->{
            synchronized(lock){
                try {
                    System.out.println("t线程开始等待");
                    lock.wait();//等待,直到被唤醒
                    System.out.println("t线程被唤醒");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    System.out.println("线程被中断");
                }
            }
        });

        t.start();
        Thread.sleep(2000);
        synchronized(lock){
            lock.notify();//唤醒lock上等待的线程
        }

获取线程实例

使用Thread.currentThread()方法可以获取到当前正在执行代码的线程实例。

代码示例:

        Thread current = Thread.currentThread();
        System.out.println("当前线程名称: "+current.getName());

        //创建并启动一个新线程
        Thread myThread = new Thread(()->{
            System.out.println("新的线程名称是: "+Thread.currentThread().getName());
        },"这个新线程名称可以自己取");
        myThread.start();

运行结果:

  • 24
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值