首页 > 其他分享 >Thread类的基本用法

Thread类的基本用法

时间:2024-10-16 16:17:37浏览次数:8  
标签:基本 run Thread void 用法 线程 重写 public

一、线程创建

1.继承Thread,重写run

package demo1;

//继承 Thread, 重写 run
class MyThread extends Thread{
    @Override
    public void run() {
        System.out.println("继承 Thread, 重写 run");
    }
}

public class Demo1 {
    public static void main(String[] args) {
        MyThread t = new MyThread();
        t.start();
    }
}

2.实现Runnable,重写run

package demo2;

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

public class Demo2 {
    public static void main(String[] args) {
        Thread t = new Thread(new MyRunnable());
        t.start();
    }
}

 3.继承Thread,重写run,使用匿名内部类

package demo3;

//继承 Thread, 重写 run, 使用匿名内部类
public class Demo3 {
    public static void main(String[] args) {
        Thread t = new Thread(){
            @Override
            public void run() {
                System.out.println("继承 Thread, 重写 run, 使用匿名内部类");
            }
        };
        t.start();
    }
}

4.实现Runnable,重写run,使用匿名内部类

package demo4;

//实现 Runnable, 重写 run, 使用匿名内部类

public class Demo4 {
    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("实现 Runnable, 重写 run, 使用匿名内部类");
            }
        });
        t.start();
    }
}

 5.使用 lambda 表达式(推荐)

package demo5;

//使用 lambda 表达式

public class Demo5 {
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> System.out.println("使用 lambda 表达式"));
        Thread t2 = new Thread(() -> {
            System.out.println("使用 lambda 表达式");
        });
        t1.start();
        t2.start();
    }
}

二、线程休眠

Thread.sleep(1000);
//休眠一秒

三、获取线程实例        

Thread.currentThread();
//用来获取当前线程的实例

四、线程中断

        在Java中,要销毁/终止一个线程,只能想办法让 run 方法尽快执行结束。

1.手动创建标志位

        线程持续工作很久,往往是因为其中有循环语句,想要让 run 方法执行结束,就是要让循环语句尽快退出。因此我们可以在代码中手动创建出标志位,来作为 run 方法执行结束的标志。

package demo6;

public class Demo6 {
    private static boolean isQuit = false;

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            while (!isQuit){
                System.out.println("线程正在工作");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("线程工作结束");
        });
        t.start();
        Thread.sleep(5000);
        isQuit = true;
    }
}

 运行结果:

        这种方法的确可以实现线程中断,但是需要手动创建标志位,而且当线程内部处于 sleep(阻塞) 状态时,不能及时响应。

2.使用 Thread 内部标志位

        Thread 类内部有一个标志位,这个标志位可以用来判定线程是否结束,即使内部处于阻塞状态,也能被唤起。

package demo6;

public class Demo6 {

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()){
// Thread.currentThread()可以获取当前线程的实例,相当于t
// t.isInterrupted()获取内部的标志位
                System.out.println("线程正在工作");
                try {
                    Thread.sleep(1000);
// 正常情况下,sleep 的休眠期到了才能唤醒,但是 interrupt() 会使 sleep 内部触发一个异常,从而提前被唤醒。
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("线程工作结束");
        });
        t.start();
        Thread.sleep(5000);
        t.interrupt();    //把对象内部的标志位设置为 true
    }
}

 运行结果:

        观察运行结果我们不难发现,主线程执行完 t.interrupt() 后,异常确实出现了,但是t线程仍在继续工作。这是因为 interrupt() 唤醒线程后,sleep 方法抛出异常,同时会自动清除刚才设置的标志位,使得标志位的效果像是没有生效。这样的设定是为了能让我们自己决定接下来如何处理。

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    //1.循环继续正常执行,相当于什么都没发生
    e.printStackTrace();

    //2.加上一个break; 相当于让线程立即结束
    //break;

    //3.可以做点其他的事情,然后再结束
    //(其他的事情)
    //break;
}

五、线程等待

        为了控制线程执行的顺序,让一个线程等待另一个线程执行结束后再执行

//在主线程中调用
t.join();    //还可以设置超时时间,如 t.join(1000) 就表示最多等待一秒。
//此时主线程等待t线程先结束

工作过程:

  1.  如果t线程正在工作中,此时调用 join 就会发生阻塞,直到超时或t线程执行结束。
  2. 如果t线程已经执行结束,此时调用 join 就会直接返回,不会涉及到阻塞。

标签:基本,run,Thread,void,用法,线程,重写,public
From: https://blog.csdn.net/2301_76907962/article/details/142979417

相关文章

  • GDSFactory dbbox() and bbox() 用法
    GDSFactorydbboxandbbox用法引言正文引言今天遇到一个问题,本人发现GDSFactory中获取box对象的边界点时可以使用dbbox(),也可以使用bbox()函数。于是对这两个函数进行了探索,发现了它们之间的微小差异,这里特来记录一下。正文首先,我们可以采用如下代码生......
  • cisco nexus7000 基本系统配置及OTV
    cisconexus7000基本系统配置1.开启cdpcdpenablecdpformatdevice-idsystem-name默认是对端设备的设备名2.ntp开启普通vdc2下开启ntp同步,先在defaultvdc上打上clockprotocolntpvdc2DC1-N7K-2(config)#ntpserver10.1.1.1use-vrfmannagementDC1-N7K-2(config)#ntpso......
  • Java Stream基本用法
    介绍JavaStream是Java8中引入的一个新的抽象概念,它允许以声明式的方式处理数据集合。Stream将要处理的元素集合视为一种流,在流的过程中,可以利用StreamAPI对元素进行各种操作,如筛选、排序、聚合等。Stream操作可以分为中间操作和终端操作,中间操作每次返回一个新的流,可以有多......
  • STM32开发————定时器的基本配置
    一、将定时器相关的.c和.h添加到新建的工程中添加文件路径:二、对.c和.h文件进行代码编写打开timer.h文件,写一下防止重复包含的宏定义#ifndef__TIMER_H#define__TIMER_H#endif打开timer.c文件,包含一下STM32的头文件:“右键单机”--->Insert'#includefi......
  • c++如何使用pthread_join函数配合pthread_create函数来创建和等待线程完成,实现线程同
    在C++中,pthread_create 和 pthread_join 是POSIX线程库(pthread)的一部分,用于创建和管理线程。pthread_create 用于创建一个新的线程,而 pthread_join 用于等待一个线程的执行完成,从而实现线程同步与控制。基本步骤使用 pthread_create 函数创建一个线程。线程的工作由......
  • linux基本指令(二)
    今天我们继续来盘Linux基本指令,如果对于前面的指令还有困惑,可以去查看之前我写的那一篇Linux基本指令(一)。mv指令(move)语法mv[选项]源文件/目录目标文件/目录功能1.移动文件或目录比如:将文件 file1.txt 移动到 /home/user/Documents/ 目录中:mvfile1.txt/home/user......
  • 列表基本知识
    什么是列表列表是由一系列的按照特定顺序排列的元素组成。在python中用方括号[]表示列表。如何访问列表 myfriend=['yzz','lzzz','hyy','skk']print(myfriend(0)myfriend=['yzz','lzzz','hyy','skk']print(myfriend(0)注意列表中第0个元素......
  • 图形用户界面-GUI的基本概念和组件之一
    前言        GUI(GraphicalUserInterface,图形用户界面,简称图形界面)编程实际是引用java.awt或javax.swing类包中的窗口类、控制组件类、布局类、事件类等,通过将控制组件类,如菜单、按钮、文本框等,直接或间接添加到窗口中,通过鼠标即可进行操作的图形化界面设计方法。ja......
  • 宏定义define的用法
    #defineread(x)scanf("%d",&x);这行代码是一个宏定义,使用了C语言中的#define指令。它的作用是定义一个名为read的宏,用于简化输入操作。具体来说:#defineread(x):这部分定义了一个宏,名字是read,它接收一个参数x。scanf("%d",&x):这是宏的替换内容,表示使用scanf函数......
  • 单链表的基本概念
    单链表的定义typedefstructLNode{intdata;structLNode*next;//定义一个指向结构体自身的指针,用来指向下一个节点}LNode,*LinkList;_____________________________________________LNode*p=LinkListp;//两种定义指针的形式,侧重点不......