重学java 38.创建线程的方式⭐

news2024/12/30 2:31:01

It is during our darkest moments that we must focus to see the light

                                                                                               —— 24.5.24

一、第一种方式_继承extends Thread方法

1.定义一个类,继承Thread
2.重写run方法,在run方法设置线程任务(所谓的线程任务指的是此线程要干的具体的事儿,具体执行的代码)
3.创建自定义线程类的对象
4.调用Thread中的start方法,开启线程,jvm自动调用run方法

package S64thread;

public class Demo195Mythread extends Thread{
    @Override
    public void run(){
        for (int i = 0; i < 10; i++) {
            System.out.println("Mythread执行了"+i);
        }
    }
}
package S64thread;

public class Demo196Test {
    public static void main(String[] args) {
        // 创建线程对象
        Demo195Mythread t1 = new Demo195Mythread();
        // 调用start方法,开启线程,jvm自动调用run方法,只有调用start才会开启线程,二者一同执行
        // t1.run();
        t1.start();
        for (int i = 0; i < 10; i++) {
            System.out.println("main线程执行了"+i);
        }
    }
}

二、多线程在内存中的运行原理 

        注意:同一个线程对象不能连续调用多次start,如果想要再次调用start,那么咱们就new一个新的线程对象

三、Thread类中的方法

package S65threadMethod;

public class Demo197Mythread extends Thread{
    @Override
    public void run(){
        for (int i = 0; i < 10; i++) {
            System.out.println(getName()+"执行了"+i);
        }
    }
}
package S65threadMethod;

public class Demo198Test {
    public static void main(String[] args) {
        // 创建线程对象
        Demo197Mythread t1 = new Demo197Mythread();

        // 给线程设置名字
        t1.setName("赵四");

        // 调用start方法,开启线程,jvm自动调用run方法,只有调用start才会开启线程,二者一同执行
        // t1.run();
        t1.start();


        for (int i = 0; i < 10; i++) {
            System.out.println("main线程执行了"+i);
        }
    }
}

void start() -> 开启线程,jvm自动调用run方法

void run() -> 设置线程任务,这个run方法是Thread重写的接口Runnable中的run方法

String getName() -> 获取线程名字
void setName(string name) -> 给线程设置名字
static Thread currentThread() -> 获取正在执行的线程对象(此方法在哪个线程中使用,获取的就是哪个线程对象

static void sleep(long millis) -> 线程睡眠超时后会自动醒来继续执行,传递的是毫秒值,睡眠时不会影响其他线程,其他线程会直接运行完,不会等待

package S65threadMethod;

public class Demo197Mythread extends Thread{
    @Override
    public void run(){
        for (int i = 0; i < 10; i++) {
            // 线程睡眠
            try{
                // 线程sleep后一顿一顿的执行
                Thread.sleep(1000L);
            }catch (InterruptedException e){
                throw new RuntimeException(e);
            }
            // 链式调用 currentThread 获取正在执行的线程对象
            System.out.println(Thread.currentThread().getName()+"线程执行了"+i);
        }
    }
}
package S65threadMethod;

public class Demo198Test {
    public static void main(String[] args) {
        // 创建线程对象
        Demo197Mythread t1 = new Demo197Mythread();

        // 给线程设置名字 线程一顿一顿的执行
        t1.setName("赵四");

        // 调用start方法,开启线程,jvm自动调用run方法,只有调用start才会开启线程,二者一同执行
        // t1.run();
        t1.start();


        for (int i = 0; i < 10; i++) {
            // 链式调用
            System.out.println(Thread.currentThread().getName()+"线程执行了"+i);
        }
    }
}

问题:为啥在重写的run方法有异常只能try,不能throws

原因:继承的 Thread中的run方法 没有抛异常,所以在子类中重写完run方法之后就不能抛,只能try…catch

四、thread中的其他方法

1.线程优先级

        ① void setPriority(int newPriority) —— 设置线程优先级,优先级越高的线程,抢到CPU使用权的几率越大,但是不是每次都先抢到

        ② int getPriority() —— 获取线程优先级

package S66thread;

import S65threadMethod.Demo197Mythread;

public class Demo200Test {
    public static void main(String[] args) {
        // 创建两个线程对象
        Demo199Mythread1 t1 = new Demo199Mythread1();
        t1.setName("金莲");

        Demo199Mythread1 t2 = new Demo199Mythread1();
        t2.setName("阿庆");

        // 获取两个线程的优先级 5是一个默认优先级
        /*
        获取两个线程的优先级
        MIN_PRIORITY=1 最小优先级 1
        NORM_PRIORITY=5 默认优先级 5
        MAX_PRIORITY=10 最大优先级 10
         */
        System.out.println(t1.getPriority());
        System.out.println(t2.getPriority());

        // 设置优先级
        t1.setPriority(1);
        t2.setPriority(10);

        System.out.println(t1.getPriority());
        System.out.println(t2.getPriority());

        t1.start();
        t2.start();
    }
}

2.守护线程

        ③ void setDaemon(boolean on) —— 设置为守护线程,当非守护线程执行完毕,守护线程就要结束,但是守护线程也不是立马结束,当守护线程结束之后,系统会告诉守护线程人家结束了,你也结束吧,在告知的过程中,守护线程会执行,只不过执行到半路就结束了

package S67ProtectThread;

public class Demo201MyThread1 extends Thread{
    @Override
    public void run(){
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+"执行了......"+i);
        }
    }
}
package S67ProtectThread;

public class Demo203MyThread2 extends Thread{
    @Override
    public void run(){
        for (int i = 0; i < 99; i++) {
            System.out.println(Thread.currentThread().getName()+"执行了..."+i);
        }
    }
}
package S67ProtectThread;

public class Demo202Test {
    public static void main(String[] args) {
        // 创建两个线程对象
        Demo201MyThread1 t1 = new Demo201MyThread1();
        t1.setName("金莲");

        Demo203MyThread2 t2 = new Demo203MyThread2();
        t2.setName("阿庆");

        // 将t2设置为守护线程
        t2.setDaemon(true);

        t1.start();
        t2.start();
    }
}

使用场景:

3.礼让线程

让两个线程尽可能的平衡一点->尽量让两个线程交替执行

        ④ static void yield() —— 礼让线程,让当前线程让出CPU使用权
场景说明:如果两个线程一起执行,可能会执行一会儿线程A,再执行一会线程B,或可能线程A执行完毕了,线程B在执行

注意:只是尽可能的平衡,不是绝对的平衡,有可能在礼让线程之后又抢到了CPU使用权

package S68PoliteThread;

public class Demo204MyThread1 extends Thread{
    @Override
    public void run(){
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+"...执行了..."+i);
            // 礼让线程
            Thread.yield();
        }
    }
}
package S68PoliteThread;

public class Demo205Test {
    public static void main(String[] args) {
        // 创建两个线程对象
        Demo204MyThread1 t1 = new Demo204MyThread1();
        t1.setName("金莲");

        Demo204MyThread1 t2 = new Demo204MyThread1();
        t2.setName("阿庆");

        // 礼让线程
        Thread.yield();
        t1.start();
        t2.start();
    }
}

     

4.插入线程      

⑤ void join() —— 插入线程或者叫做插队线程

package S69InsertThread;

public class Demo206MyThread1 extends Thread{
    @Override
    public void run(){
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+"...执行了..."+i);
            // 插入线程
        }
    }
}
package S69InsertThread;

public class Demo207Test {
    public static void main(String[] args) throws InterruptedException {
        // 创建两个线程对象
        Demo206MyThread1 t1 = new Demo206MyThread1();
        t1.setName("金莲");
        t1.start();
        // 插入线程 表示把t1插入到当前线程之前
        t1.join();
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+"...执行了..."+i);
            // 插入线程
        }
        t1.start();
    }
}

五、第二种方式_实现Thread中的Runnable接口

Thread中的run方法重写的Runnable中的接口,可以直接实现Runnable接口

1.创建类,实现Runnable接口
2.重写run方法,设置线程任务
3.利用Thread类的构造方法:Thread(Runnable target),创建Thread对象(线程对象),将自定义的类当参数传递到Thread构造中 —> 这一步是让我们自己定义的类成为一个真正的线程类对象

4.调用Thread中的start方法,开启线程,jvm虚拟机自动调用run方法

package S70ThreadRunnable;

public class MyRunnable implements Runnable{
    @Override
    public void run(){
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+"...执行了"+i);
        }
    }
}
package S70ThreadRunnable;

public class Demo208Test {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();

//        Thread(Runnable target)
        Thread t1 = new Thread(myRunnable);
        // 调用Thread中的start方法,开启线程
        t1.start();

        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+"...执行了"+i);
        }
    }
}

六、两种实现多线程的方式区别

1.继承Thread:继承只支持单继承,有继承的局限性
2.实现Runnable:没有继承的局限性,MyThread extends Fu implements Runnable

七、匿名内部类方式创建多线程

        严格意义上来说,匿名内部类方式不属于创建多线程方式其中之一,因为匿名内部类形式建立在实现Runnable接口的基础上完成的

        匿名内部类回顾:
                1.new 接口/抽象类(){

                        重写方法

                  }.重写的方法();
                2.接口名/类名对象名 = new 接口/抽象类(){

                        重写方法

                  }        
                  对象名.重写的方法();

匿名内部类给线程取名
Thread(Runnable target,string name)

        name指的是给匿名内部类中的线程设置名字

package S70ThreadRunnable;

public class Demo209Test02 {
    public static void main(String[] args) {
    /*
        Thread(Runnable r)
     */

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName()+"...执行了"+i);

                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName()+"...执行了"+i);

                }
            }
        }).start();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1688322.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

光伏企业都在用的户用光伏管理软件——鹧鸪云

随着全球对可再生能源和清洁能源的需求日益增长&#xff0c;光伏产业作为其中的佼佼者&#xff0c;正迎来前所未有的发展机遇。然而&#xff0c;随着光伏电站规模的扩大和分布范围的增加&#xff0c;如何高效、智能地管理这些电站&#xff0c;确保它们稳定、安全地运行&#xf…

做好商业分析,帮你用有限的资源选择高效益项目实现战略目标

对于组织来说&#xff0c;资源条件总是有限的&#xff0c;为了实现战略目标&#xff0c;则需要从众多项目中筛选出最合适的项目来实现收益。但项目的筛选往往会遇到很多难点&#xff0c;如信息收集不全影响筛选的准确性、评估标准不明确或难以量化、决策过程复杂等等。 那么如何…

【NumPy】关于numpy.reshape()函数,看这一篇文章就够了

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

java如何获取IP和IP的归属地?

在Java中&#xff0c;获取IP地址通常指的是获取本地机器的IP地址或者通过某种方式&#xff08;如HTTP请求&#xff09;获取的远程IP地址。代码案例如下: 而要获取IP的归属地&#xff08;地理位置信息&#xff09;&#xff0c;则通常需要使用第三方IP地址查询服务&#xff0c;我…

【JAVA |再谈接口、Object、内部类】Object类中子类重写,Cloneable 接口、比较器、内部类

✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心哦&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; &#x1f388;丠丠64-CSDN博客&#x1f388; ✨✨ 帅哥美女们&#xff0c;我们共同加油&#xff01;一起…

element-plus:踩坑日记

el-table Q&#xff1a;有fixed属性时&#xff0c;无数据时&#xff0c;可能出现底部边框消失的bug 现象&#xff1a; 解决方法&#xff1a; .el-table__empty-block {border-bottom: 1px solid var(--el-table-border-color); } el-collapse 折叠面板 Q&#xff1a;标题上…

Java操作Word文档,根据模板生成文件

Java操作Word文档 poi-tl介绍 官方文档&#xff1a;https://deepoove.com/poi-tl/ poi-tl&#xff08;poi template language&#xff09;是Word模板引擎&#xff0c;使用模板和数据创建很棒的Word文档。 在文档的任何地方做任何事情&#xff08;Do Anything Anywhere&#…

在全志H616核桃派开发板上配置I2C引脚并读取温度数据

配置引脚 找到板子上的i2c引脚 为了方便查找&#xff0c;我们加入了一个显示功能引脚位置的功能&#xff0c;运行以下命令&#xff0c;查看板子的40pin引脚上有几个可用i2c gpio pin i2c启用i2c 我们使用set-device指令来使能/关闭指定设备的底层驱动&#xff0c;使能后&am…

视频汇聚/云存储/安防监控EasyCVR接入GB28181设备未回复ack信息的原因排查

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。 用户反馈&#xff0c;设备通过国标GB28181注…

Docker 容器间通讯

1、虚拟ip/访问 同一网络 安装docker时&#xff0c;docker会默认创建一个内部的桥接网络docker0&#xff0c;每创建一个容器分配一个虚拟网卡&#xff0c;容器之间(包括宿主机)可以根据分配的ip互相访问(ps:其他主机(包括其他主机的容器)无法ping通docker容器ip无法访问&#…

RepOptimizer原理与代码解析(ICLR 2023)

paper&#xff1a;Re-parameterizing Your Optimizers rather than Architectures offcial implementation&#xff1a;https://github.com/dingxiaoh/repoptimizers 背景 神经网络的结构设计是将先验知识融入模型中。例如将特征转换建模成残差相加的形式&#xff08;\(yf(x…

Zoho CRM怎么样?云衔科技为企业提供采购优惠!

企业对于客户关系管理&#xff08;CRM&#xff09;系统的需求日益增加&#xff0c;Zoho CRM作为一款备受赞誉的国际CRM服务提供商&#xff0c;凭借其全面的功能、出色的用户体验和卓越的性价比&#xff0c;成为了众多企业数字化转型的得力助手。 Zoho CRM是一款覆盖客户全生命…

Vue状态管理深度剖析:Vuex vs Pinia —— 从原理到实践的全面对比

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 &#x1f44b; 引言&#x1f4cc; Vuex 基础知识核心构成要素示例代码 &#x1f4cc; Pinia 基础知识核心构成要素示例代码 &#x1f4cc; Vuex与Pinia的区别&#x1f4cc; 使用示例与对比&#x1f4cc; 总结 &#x1f44b;…

Transormer(2)-位置编码

位置编码公式 偶数位置用sin,奇数位置用cos. d_model 表示token的维度&#xff1b;pos表示token在序列中的位置&#xff1b;i表示每个token编码的第i个位置&#xff0c;属于[0,d_model)。 torch实现 import math import torch from torch import nn from torch.autograd im…

Vue 3 的 setup语法糖工作原理

前言 我们每天写vue3项目的时候都会使用setup语法糖&#xff0c;但是你有没有思考过下面几个问题。setup语法糖经过编译后是什么样子的&#xff1f;为什么在setup顶层定义的变量可以在template中可以直接使用&#xff1f;为什么import一个组件后就可以直接使用&#xff0c;无需…

【如何让论文中摘要后面的内容不出现在目录中】

首先选择摘要二字&#xff0c;设置为一级标题&#xff0c;然后选择摘要后面的内容设置为正文样式&#xff0c;再选择这一部分看一下是不是都是正文大纲级别&#xff0c;如果是那就可以了。 具体流程如下 1、选择摘要二字&#xff0c;设置为一级标题样式 2、选择摘要后面的文…

FreeRTOS学习——FreeRTOS队列(下)之队列创建

本篇文章记录我学习FreeRTOS队列创建的知识。主要分享队列创建需要使用的初始化函数、队列复位函数。 需要进一步了解FreeRTOS队列的相关知识&#xff0c;读者可以参考以下文章&#xff1a; FreeRTOS学习——FreeRTOS队列&#xff08;上&#xff09;_freertos 单元素队列-CSDN博…

scikit-learn机器学习要点总结

目录 一、机器学习总体流程二、引入数据集三、将数据集转换为DataFrame四、可视化数据五、数据预处理&#xff08;一&#xff09;数据标准化&#xff08;二&#xff09;独热编码 六、数据集划分为训练集和测试集七、创建模型估计器(estimator)&#xff08;一&#xff09;用于回…

人力资源(HR)OKR 案例

HR人员 #OKR# 是一个很好的方法来建立一致性&#xff0c;吸引团队成员&#xff0c;并实现高绩效。 在本文中&#xff0c;我们将回答以下问题&#xff1a; 如何写好HR OKR &#xff1f; 什么是好的HR OKR 的例子 &#xff1f; 我应该在我的HR OKR 中填写什么 &#xff1f; 如何…

stream( ).collect ( Collectors.groupingBy ( ) ) 的用法

文章目录 第一种解释1、基本用法2、指定值收集器3、多级分组4、常见应用场景和用处 第二种解释1、基本语法2、示例3、更复杂的用法 第一种解释 Collectors.groupingBy 是 Java 8 引入的 Stream API 中的一个收集器&#xff08;Collector&#xff09;&#xff0c;它用于将流&am…