当前位置: 首页 > news >正文

Thread类的基本用法

线程创建

通过Thread类创建

通过继承 Thread 类并重写run方法就可以实现多线程;在 Thread 类中 提供了start方法启动新线程

class MyThread extends Thread{
    public void run(){
        System.out.println("MyThread中的run方法已执行");
    }
}
public class Main{
    public static void main(String[] args) {
        MyThread t=new MyThread();
        Thread thread=new Thread(t);
        thread.start();
    }
}

 通过Runnable接口创建

java只支持单继承,如果一个类继承了某个父类就没办法再继承 Thread 类了,因此,Thread类提供了另一种构造方法Thread (Runnable target)构传的参数实现了Runnable接口的对象,Runnable接口中只有一个run方法,创建线程时实现Runnable接口中的run方法作为运行代码,不需要再调用Thread类中的run方法。

class MyThread implements Runnable{
    public void run(){
        System.out.println("Runnable接口创建的线程已运行");
    }
}
public class Main{
    public static void main(String[] args){
        MyThread runnable=new MyThread();
        Thread thread=new Thread(runnable);
        thread.start();
    }
}

通过Callable接口创建

在以上两种方法中创建线程的时候,里面的run方法都没有返回值,如果想要在run方法中获取返回值,就可以通过Callable接口来创建线程

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ExecutionException;

class MyThread4 implements Callable<Object>{
    @Override
    public Object call() throws Exception {
        System.out.println("call方法已执行");
        return 0;
    }
}
class Main{
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyThread4 mt=new MyThread4();
        FutureTask<Object> ft=new FutureTask<>(mt);
        Thread thread=new Thread(ft,"thread");
        thread.start();
        //获取返回值
        System.out.println(ft.get());
    }
}

Callable 接口的实现的多线程是通过 FutureTask 类来进行封装和管理返回结果的,FutureTask 类的直接父接口是RunnableFuture,想必从名字我们就能看出它一定跟Runnable 接口有关系。RunnableFuture是Runnable和Future的结合体。看下图它们之间的关系:

 

 在上图中我们可以看出,FutureTask是 Runnable 接口与 Future 接口的实现类。

线程创建的方式有多种,这里只列举了三种

其实严格来说,线程的创建方式只有通过new Thread().start()来创建,不管通过哪种方式最终都需要通过new Thread().start()创建。更加详细的描述可以看这篇文章大家都说Java有三种创建线程的方式!并发编程中的惊天骗局!

线程中断

线程中断指的是在线程运行过程中,手动中断线程的执行。

比如说,我写了一个多线程的代码,线程正在执行中,但是因为网速太辣鸡导致线程一直处于运行的状态,它不结束,我想停掉这个线程。

在 java 中执行线程中断有两个常用的方法:

  • 通过共享的标记进行中断
  • 使用 interrupt() 方法中断

第一种:

使用自定义的标志位

public class ThreadDemo {
    private static class MyRunnable implements Runnable{
        public volatile boolean isStop=false;
        public void run(){
            while(!isStop){
                System.out.println(Thread.currentThread().getName()+"正在加载中……");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyRunnable target=new MyRunnable();
        Thread thread=new Thread(target);
        thread.start();
        Thread.sleep(10*1000);
        target.isStop=true;
        System.out.println("线程已中断");
    }
}

第二种:

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

public void interrupt()  中断对象关联的线程,如果线程正阻塞,通过异常来通知,否则设置标志位

public class ThreadDemo{
    private static class MyRunnable implements Runnable{
        @Override
        public void run(){
            while( !Thread.interrupted()){//或者  !Thread.interrupted()
                System.out.println(Thread.currentThread().getName()+"正在加载中……");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    System.out.println("线程已中断");
                    break;
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyRunnable target=new MyRunnable();
        Thread thread=new Thread(target);
        thread.start();
        Thread.sleep(10*1000);
        thread.interrupt();

    }
}

线程等待 -join()

有时候,我们想要在某个线程结束后再执行后面的任务,我们就需要线程等待,假如月光族张三想换个新手机,但是发现老板还没发工资,他就没钱买,只能等到老板发工资后再买

public class ThreadDemo3 {
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable=()->{
            for(int i=0;i<10;i++){
                try {
                    System.out.println(Thread.currentThread().getName()+"没钱!");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName()+"有钱了");
        };
        Thread thread1=new Thread(runnable,"老板");
        Thread thread2=new Thread(runnable,"张三");
        thread1.start();
        thread1.join();
        thread2.start();
        thread2.join();
        System.out.println("张三买到手机了");
    }
}

线程休眠

让线程休眠的方法如下:

  • public static void sleep(long millis) throws InterruptedException  休眠当前线程millis毫秒
  • public static void sleep(long millis,int nanos)throws InterruptedException 更高精度的休眠
public class ThreadDemo1 {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("当前时刻:"+System.currentTimeMillis());
        Thread.sleep(3000);
        System.out.println("当前时刻:"+System.currentTimeMillis());
    }
}

获取线程实例

我们可以通过以下的方法进行获取:

public static Thread currentThread();

public class ThreadDemo {
    public static void main(String[] args) {
        Thread thread=Thread.currentThread();
        System.out.println(thread);
    }
}

相关文章:

  • 用Webpack 基础配置快速搭建项目开发环境
  • 支持多项检测的多段环形光源 助力金属零件缺陷检测
  • Wincc7.5 对于此版本的wincc,许可证的存储介质必须插入usb接口
  • 项目风险的早期识别与应对清单
  • Swift观察机制新突破:如何用AsyncSequence实现原子化数据监听?
  • prime 1 靶场笔记(渗透测试)
  • 开源技术如何助力中小企业实现财务管理自主化?
  • 将你的 Rust + WebAssembly 项目发布到 npm
  • 开源项目 | 17款云原生安全相关的扫描和平台类开源工具
  • 开关电源输出过冲抑制设计方法
  • 选导师原理
  • 无人机3S与4S电池技术对比!
  • 【数据结构】反射、枚举以及lambda表达式
  • Spring 框架源码
  • 【更新至2023年】2000-2023年中国气候政策不确定性指数(全国、省、市三个层面)
  • C# 13新特性 - .NET 9
  • linux命令七
  • 老龄化遇上数字化丨适老化改造:操作做“减法”,服务做“加法”
  • Guava Cache的refreshAfterWrite机制
  • CExercise_06_1递归_1汉诺塔_2对于n个盘子的汉诺塔问题,给定一个整数m,要求在控制台打印出m + 1步的移动轨迹。
  • 成功卫冕!孙颖莎4比0战胜蒯曼,获澳门世界杯女单冠军
  • 俄“联盟MS-26”载人飞船安全返回地球
  • 闲置书换蔬菜,浙江嘉善启动全民阅读系列活动
  • 一季度江西GDP达7927.1亿元,同比增长5.7%
  • 郑州一废弃饭店堆砌物起火:明火被扑灭,未造成人员伤亡
  • 特朗普称美联储主席鲍威尔“应该尽早下台”