Thread类的基本用法

妖狐艹你老母 2024-04-23 20:32 158阅读 0赞

⭐ 作者:小胡_不糊涂
? 作者主页:小胡_不糊涂的个人主页
? 收录专栏:JavaEE
? 持续更文,关注博主少走弯路,谢谢大家支持 ?

Thread

    1. 线程创建
    • 1.1 继承Thread类
    • 1.2 实现Runnable接口
    • 1.3 使用匿名内部类创建Thread子类对象
    • 1.4 使用匿名类创建 Runnable 子类对象
    • 1.5 使用lambda 表达式
    1. 线程中断
    • 2.1 使用自定义的变量来作为标记位
    • 2.2 调用interrupt()方法来通知
    1. 线程等待-join()
    1. 线程休眠-sleep()
    1. 获取线程实例

在这里插入图片描述

1. 线程创建

1.1 继承Thread类

  1. class MyThread extends Thread{
  2. public void run(){
  3. System.out.println("继承Thread,重写run");
  4. }
  5. }
  6. public class TestDemo1{
  7. public static void main(String[] args) {
  8. MyThread thread = new MyThread();
  9. thread.start();//启动线程
  10. }
  11. }

1.2 实现Runnable接口

  1. class MyRunnable implements Runnable{
  2. public void run(){
  3. System.out.println("实现Runnable接口");
  4. }
  5. }
  6. public class TestDemo1{
  7. public static void main(String[] args) {
  8. Thread thread=new Thread(new MyRunnable());
  9. thread.start();
  10. }
  11. }

1.3 使用匿名内部类创建Thread子类对象

  1. public class TestDemo1{
  2. public static void main(String[] args) {
  3. Thread thread=new Thread(){
  4. public void run(){
  5. System.out.println("这是一个线程");
  6. }
  7. };
  8. thread.start();
  9. }
  10. }

1.4 使用匿名类创建 Runnable 子类对象

  1. public class TestDemo1{
  2. public static void main(String[] args) {
  3. Thread thread=new Thread(new Runnable(){
  4. public void run() {
  5. System.out.println("实现Runnable,重写run,使用匿名内部类");
  6. }
  7. });
  8. thread.start();//启动线程
  9. }
  10. }

1.5 使用lambda 表达式

  1. public class TestDemo1{
  2. public static void main(String[] args) {
  3. Thread thread=new Thread(()->{
  4. System.out.println("使用lambda表达式");
  5. });
  6. thread.start();
  7. }
  8. }

2. 线程中断

当我们想要让一个正在执行的线程停止时,该怎么做呢?

2.1 使用自定义的变量来作为标记位

  1. ublic class TestDemo2 {
  2. private static volatile boolean isquit=false;
  3. public static void main(String[] args) {
  4. Thread thread=new Thread(()->{
  5. while(!isquit){
  6. System.out.print(Thread.currentThread().getName());
  7. System.out.println("线程工作中...");
  8. }
  9. try {
  10. Thread.sleep(1000);
  11. } catch (InterruptedException e) {
  12. throw new RuntimeException(e);
  13. }
  14. //线程运行完毕
  15. System.out.println("线程工作完毕");
  16. });
  17. thread.start();
  18. try {
  19. Thread.sleep(2000);
  20. } catch (InterruptedException e) {
  21. e.printStackTrace();
  22. }
  23. isquit = true;
  24. System.out.println("让 thread 线程结束!");
  25. }
  26. }

需要给标志位上加 volatile 关键字才能进行修改

2.2 调用interrupt()方法来通知






















方法 说明
public void interrupt() 中断对象关联的线程
public static boolean interrupted() 判断当前线程的中断标志位是否设置
public bool isInterrupted() 判断对象关联的线程标志位是否设置
  1. public class TestDemo2 {
  2. public static void main(String[] args) throws InterruptedException {
  3. Thread thread=new Thread(()-> {
  4. //while(!Thread.interrupted()){
  5. while (!Thread.currentThread().isInterrupted()) {
  6. System.out.println("线程工作中...");
  7. try {
  8. Thread.sleep(1000);
  9. } catch (InterruptedException e) {
  10. break;
  11. }
  12. }
  13. });
  14. thread.start();
  15. Thread.sleep(2000);
  16. // 使用一个 interrupt 方法, 来修改刚才标志位的值
  17. System.out.println("让 thread 线程结束");
  18. thread.interrupt();
  19. }
  20. }

thread 收到通知的⽅式有两种:

  1. 如果线程因为调⽤ wait/join/sleep 等⽅法⽽阻塞挂起,则以 InterruptedException 异常的形式通知,清除中断标志。
    当出现 InterruptedException 的时候,要不要结束线程取决于catch 中代码的写法。可以选择忽略这个异常,也可以跳出循环结束线程。
  2. 否则,只是内部的⼀个中断标志被设置,thread 可以通过。
    Thread.currentThread().isInterrupted()判断指定线程的中断标志被设置,不清除中断标志,这种方式通知收到的更及时,即使线程正在 sleep 也可以马上收到。

3. 线程等待-join()

有时,我们需要等待⼀个线程完成它的⼯作后,才能进⾏⾃⼰的下⼀步⼯作。

  1. public class TestDemo3{
  2. public static void main(String[] args) throws InterruptedException {
  3. Thread t = new Thread(() -> {
  4. int n = 5;
  5. for (int i = 0; i < n; i++) {
  6. System.out.println("我是一个线程, 正在工作中...");
  7. try {
  8. Thread.sleep(1000);
  9. } catch (InterruptedException e) {
  10. e.printStackTrace();
  11. }
  12. }
  13. System.out.println("线程执行结束");
  14. });
  15. t.start();
  16. t.join(); // 线程等待
  17. System.out.println("这是主线程, 期望在 thread 结束后打印");
  18. }
  19. }

在这里插入图片描述

如果将t.join()注释,结果会是什么呢?
在这里插入图片描述






















方法 说明
public void join() 等待线程结束
public void join(long millis) 等待线程结束,最多等待millis毫秒
public void join(long millis,int nanos) 同上

4. 线程休眠-sleep()

为线程的调度是不可控的,所以,该⽅法只能保证实际休眠时间是⼤于等于参数设置的休眠时间的。


















方法 说明
public static void sleep(long millis) throws InterruptedException 休眠当前线程run方法
public static void sleep(long millis,int nanos) throws InterruptedException 可以更高精度的休眠线程
  1. public class TestDemo4 {
  2. public static void main(String[] args) throws InterruptedException {
  3. Thread t1=new Thread(()->{
  4. System.out.println("t1正在执行");
  5. });
  6. Thread t2=new Thread(()->{
  7. System.out.println("t2正在执行");
  8. });
  9. t1.start();
  10. t2.start();
  11. }
  12. }

上面的执行过程中,我们无法控制t1与t2的先后执行顺序,运行时就会产生:
在这里插入图片描述

但是当我们让main线程在执行t1线程时,进入有限的休眠状态,就可以保证t2不会来干扰t1

  1. public class TestDemo4 {
  2. public static void main(String[] args) throws InterruptedException {
  3. Thread t1=new Thread(()->{
  4. System.out.println("t1正在执行");
  5. });
  6. Thread t2=new Thread(()->{
  7. System.out.println("t2正在执行");
  8. });
  9. t1.start();
  10. Thread.sleep(1000);
  11. t2.start();
  12. }
  13. }

在这里插入图片描述

5. 获取线程实例














方法 说明
public static Thread currentThread(); 返回当前线程对象的引用
  1. public class TestDemo5 {
  2. public static void main(String[] args) {
  3. Thread thread=Thread.currentThread();
  4. System.out.println(thread.getId());//1
  5. System.out.println(thread.getName());//main
  6. }
  7. }
  8. public class TestDemo5 {
  9. public static void main(String[] args) {
  10. // Thread thread=Thread.currentThread();
  11. Thread thread=new Thread();
  12. System.out.println(thread.currentThread().getId());//1
  13. System.out.println(thread.getName());//Thread-0
  14. }
  15. }

发表评论

表情:
评论列表 (有 0 条评论,158人围观)

还没有评论,来说两句吧...

相关阅读