IT俱乐部 Java Java标准库中Thread类的基本用法总结大全

Java标准库中Thread类的基本用法总结大全

前言

线程是操作系统中的概念,操作系统内核实现了线程这样的概念,并且对用户层提供了一些api,供用户使用。在Java标准库中,Thread
类可以视为是对操作系统提供的api进一步的抽象和封装。

Thread 类的基本用法有:

一、线程创建

想要实现多线程编程,第一步就是需要创建一个线程。在Java中创建线程的方式有多种方式,下面介绍五种常见的创建方式:

方式1:继承Thread类,重写run方法!

  • 创建一个继承Thread类的子类
  • 重写run()方法,编写线程执行的代码
  • 创建子类实例并调用start()方法启动线程

优点:编码简单

缺点:Java是单继承,继承Thread后无法继承其他类

class MyThread extends Thread{
    @Override
    public void run() {
        System.out.println("方式1:继承Thread类,重写run方法!");
    }
}

//创建对象,并调用start()方法启动线程
Thread t = new MyThread();
t.start();

方式2:实现 Runnable, 重写 run方法

  • 创建一个实现Runnable接口的类
  • 实现run()方法,编写线程执行的代码
  • 创建Thread实例,传入Runnable实现类对象

优点:可以继承其他类,实现多个接口,更灵活

class MyRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println("方式2:实现 Runnable, 重写 run");
    }
}

//创建对象,并调用start()方法启动线程
Thread t = new Thread(new MyRunnable());
t.start();

方式3: 继承Thread, 重写run, 使用匿名内部类

  • 直接创建Thread的匿名子类
  • 在匿名内部类中重写run()方法
  • 适用于简单、一次性使用的线程
Thread t = new Thread(){
	@Override
	public void run() {
		System.out.println("方式3:继承Thread, 重写run, 使用匿名内部类");
	}
};

方式4: 实现Runnable, 重写run, 使用匿名内部类

  • 创建Runnable接口的匿名实现类
  • 在匿名内部类中实现run()方法
  • 将匿名Runnable对象传递给Thread构造函数
  • 比继承Thread的匿名内部类更灵活
Thread t = new Thread(new Runnable() {
	@Override
	public void run() {
		System.out.println("方式4: 实现Runnable, 重写run, 使用匿名内部类");
	}
});

方式5: 使用lambda表达式

  • Runnable是函数式接口,可以使用lambda表达式
  • 语法简洁,适合简单的线程任务
  • 代码更简洁
Thread t = new Thread(()->{
	System.out.println("方式5: 使用lambda表达式");
});

二、线程中断 – interrupt()

线程一旦启动进入工作状态,它就会根据代码编写的步骤去执行,一直到完成为止才结束。但是有时需临时打断它的执行,Thread类中提供了interrupt方法去实现这一功能。

interrupt() 是 Thread类的一个实例方法,用于中断线程。它设置线程的中断状态标志,但不会强制停止线程的执行。线程自身需要检查中断状态并决定如何响应。

thread.interrupt(); // 设置线程的中断标志位为 true

Thread.interrupted(); // 检查当前线程是否被中断(会清除中断状态)

thread.isInterrupted(); // 检查对象关联的线程是否被中断(不会清除中断状态)

例如下面代码实现中断:

public class Demo3 {
    public static void main(String[] args) throws InterruptedException {
        Thread worker = new Thread(() -> {
           while(!Thread.interrupted()){
               System.out.println("工作中...");
           }
            System.out.println("线程正常结束");
        });

        worker.start();//启动线程
        Thread.sleep(3000);//让线程工作三秒
        worker.interrupt(); //中断线程
    }
}

结果:

我们让线程工作三秒钟,此时while循环每次循环开始前检查中断状态,当执行执行中断指令后,线程结束循环,但线程不会强制停止线程的执行,继续把线程正常结束语句继续打印完后再结束。

另外,如果线程因为调用wait/join/sleep等方法而阻塞挂起,则以InterruptionException异常的形式抛出,中断状态会被清除(变为 false),如果不重新设置中断状态,while 循环会继续执行!

所以要在catch后恢复中断状态,确保了中断信号不会丢失,从而让while 循环的条件检查能检测到中断,线程就能正常退出。

public class Demo3 {
    public static void main(String[] args) throws InterruptedException {
        Thread worker = new Thread(() -> {
           while(!Thread.currentThread().isInterrupted()){
               System.out.println("工作中...");
               try {
                   Thread.sleep(1000);//sleep() 被中断时:会抛出 InterruptedException 并清除中断状态(false)
               } catch (InterruptedException e) {
                   System.out.println("线程在sleep时被中断");
                   Thread.currentThread().interrupt(); //中断状态恢复为true
                                                        //确保了中断信号不会丢失,
                                                        //确保了while 循环的条件检查能检测到中断
                                                        //确保了线程能正常退出
               }
           }
            System.out.println("线程正常结束");
        });

        worker.start();//启动线程
        Thread.sleep(1000);//让线程工作三秒
        worker.interrupt(); //中断线程
    }
}

三、线程等待 – join()

有时候,当有多个线程并发工作时,可能需要某个线程先执行完任务后,后一个线程再根据前一个线程执行结束的结果去进行自己的下一步工作时,就需要有一个先后执行顺序,此时可以使用join方法去实现。
栗如:

public class Demo {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.print("1");
            }
        });
        t.start();
        t.join();
        System.out.print("2");
    }
}

当主线程创建一个新线程 t 后,我们调用start方法启动线程,再调用join方法让main主线程等待,等打印完 “1” 后,主线程再执行打印 “2” 操作,因此最终结果为 “12”。

如果不使用join方法,会出现两种结果,分别是“12” 或者是“21”。因此t线程和main线程是并发执行的,他们的执行顺序都是操作系统随机调度的,为了保证结果为 “12”,就得保证t线程优先执行,此时就可以调用join方法,使main线程等待。

四、线程休眠 – sleep()

调用sleep方法可以使线程暂时进入休眠状态,单位为毫秒,比如sleep(3000)就是休眠三秒钟。

五、获取线程实例 – currentThread()

返回当前线程对象的引用

例如:

小结

以上就是Java标准库中Thread类的一些基本用法,由于个人水平有限,如有不足之处,欢迎一起交流学习共同进步!

到此这篇关于Java标准库中Thread类的基本用法总结大全的文章就介绍到这了,更多相关Java标准库Thread类用法内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章希望大家以后多多支持IT俱乐部!

本文收集自网络,不代表IT俱乐部立场,转载请注明出处。https://www.2it.club/code/java/17279.html
下一篇
联系我们

联系我们

在线咨询: QQ交谈

邮箱: 1120393934@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部