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

Thread类的基本用法

1.线程创建

1.继承Thread类,重写run()方法

class MyThread extends Thread{
    @Override
    public void run() {
        System.out.println("hello thread");
    }
}
public class Demo1 {
    public static void main(String[] args) {
        MyThread t=new MyThread();//把线程和线程要完成的任务耦合在一起
        t.start();//另外启动新线程,执行run中的逻辑,是一个单独执行流,和现有执行流不相关。并发执行
        System.out.println("hello main");
    }
}

2.实现Runnable接口,重写run()方法

class MyRunnable implements Runnable{
    @Override
    public void run() {
        while (true) {
            System.out.println("hello MyRunnable");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
public class Demo2 {
    public static void main(String[] args) {
        MyRunnable myRunnable=new MyRunnable();
        Thread t=new Thread(myRunnable);//把线程要干的事和线程分开,使用Runnable专门表示线程要完成的工作
        t.start();
        while (true){
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

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

public class Demo3 {
    /**
     *使用匿名内部类,创建thread子类同时实例化出一个thread对象
     * @param args
     */
    public static void main(String[] args) {
        Thread t=new Thread(){
            @Override
            public void run() {
                while(true){
                    System.out.println("hello thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };
        t.start();
        while(true){
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

4.实现Runnable接口,使用匿名内部类

public class Demo4 {
    /**
     * 使用匿名内部类 实现Runnable接口
     * @param args
     */
    public static void main(String[] args) {
        Thread t=new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    System.out.println("hello thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        });
        t.start();
        while(true){
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

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

public class Demo5 {
    /**
     * lambda表达式,推荐写法
     * @param args
     */
    public static void main(String[] args) {
        Thread t=new Thread(()->{
            while (true){
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t.start();
        while(true){
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

2.启动线程(start和run的区别)

class MyThread extends Thread{
    @Override
    public void run() {
        while(true) {
            System.out.println("hello thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
public class Demo1 {
    public static void main(String[] args) {
        MyThread t=new MyThread();
        //t.run();直接调用run
        t.start();
        while (true){
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

 第一个截图是调用start,是创建线程,在新线程里面执行代码,和main线程并发执行。

第二个截图是调用run,没有创建线程,而是在原来的main线程执行代码

线程中断

本质是让run方法快点结束,而不是让run执行一般中止。

方法1:自己定义一个标志位,作为线程是否结束的标志

public class Demo9 {
    public static boolean isQuit=false;//自定义一个标志
    public static void main(String[] args) {
        Thread t=new Thread(()->{
            while (!isQuit) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t.start();

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        isQuit=true;//3秒后线程结束
    }
}

方法2:使用标准库自带的标记

public class Demo10 {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                //currentThread()是一个静态方法,通过它可以获得当前线程对应的Thread对象
                //isInterrupted()用于判定标志位
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    //throw new RuntimeException(e);

                    //1.立即结束线程
                    //break;

                    //2.不做处理

                    //3.稍后处理
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException ex) {
                        throw new RuntimeException(ex);
                    }
                    break;
                }
            }
        });
        t.start();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        t.interrupt();//通过他中断线程,设置标志位为true
        /*
        interrupt方法有两种情况
        1.t线程在运行时,会设置标志位为true
        2.t线程在阻塞状态(sleep),不会设置标志位,而是触发InterruptedException,这个异常会把sleep提前唤醒.
        所以处理异常时直接break;
         */
    }
}

线程等待

线程之间的调度是不确定的,可以通过join()方法控制线程的结束顺序

public class Demo11 {
    public static void main(String[] args) {
        Thread t=new Thread(()->{
            for (int i = 0; i < 5; i++) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t.start();
        try {
            t.join();//main线程进入阻塞,t线程继续参与调度
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("hello main");

    }
}

如果调用join方法之前,t线程已经结束,此时join不需要阻塞等待。

线程休眠sleep() 

操作系统管理线程PCB的时候,是有多了链表的。其中有阻塞队列,就绪队列,调用sleep()时PCB会从 就绪队列移动 到 阻塞队列。只有就绪队列才会参与cpu调度,当sleep时间到了就会从新回到就绪队列(不代表立即在cpu上执行)

相关文章:

  • Vue——方法与事件、 样式绑定、数据绑定、面试题、笔试题
  • DCDC Bootstrap自举电路
  • 练习前端案例
  • Completed 404 NOT_FOUND,Whitelabel Error Page
  • 微信公众号多题库查题系统
  • Vue事件
  • TCP/IP协议专栏——ARP详解——网络入门和工程维护必看
  • python 字符串类型
  • 【canvas】-- H5新增标签canvas的简单用法
  • C#实现根据字体名称获取字体文件名
  • Android开发-视图view讲解
  • Vue样式绑定
  • 机器学习分类
  • 计算机毕业设计ssm水果库存管理系统30q2h系统+程序+源码+lw+远程部署
  • 小红书和中兴笔试
  • SegmentFault for Android 3.0 发布
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • Android组件 - 收藏集 - 掘金
  • Cookie 在前端中的实践
  • Electron入门介绍
  • hadoop集群管理系统搭建规划说明
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • uni-app项目数字滚动
  • 开源中国专访:Chameleon原理首发,其它跨多端统一框架都是假的?
  • 深度学习入门:10门免费线上课程推荐
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • 微服务核心架构梳理
  • 微信开放平台全网发布【失败】的几点排查方法
  • 线上 python http server profile 实践
  • ​第20课 在Android Native开发中加入新的C++类
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • ${factoryList }后面有空格不影响
  • $redis-setphp_redis Set命令,php操作Redis Set函数介绍
  • (1)STL算法之遍历容器
  • (LeetCode C++)盛最多水的容器
  • (python)数据结构---字典
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (初研) Sentence-embedding fine-tune notebook
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (接口自动化)Python3操作MySQL数据库
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (五)c52学习之旅-静态数码管
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (转)C#调用WebService 基础
  • (转载)利用webkit抓取动态网页和链接
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • .h头文件 .lib动态链接库文件 .dll 动态链接库
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • .NET 5种线程安全集合
  • .NET delegate 委托 、 Event 事件,接口回调
  • .NET Framework Client Profile - a Subset of the .NET Framework Redistribution
  • .net 程序发生了一个不可捕获的异常
  • .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?