【Java】多线程-线程创建的两种方式【主线学习笔记】

文章目录


前言

Java是一门功能强大且广泛应用的编程语言,具有跨平台性和高效的执行速度,广受开发者喜爱。在接下来的学习过程中,我将记录学习过程中的基础语法、框架和实践技巧等,分享学习心得,对自己学习过程进行整理和总结,也希望能为其他学习Java的朋友提供一些帮助和参考。


创建线程的方式之一:继承Thread类

步骤

  1. 创建一个继承于Thread类的子类
  2. 重写Thread类的run()-->将此线程要执行的操作,声明在此方法中
  3. 创建当前Thread的子类对象
  4. 通过该对象调用start()启动线程

1.2例题:创建一个分线程1,用于遍历100以内的偶数,再创建一个分线程2,用于遍历100以内的偶数

代码:

java 复制代码
public class EvenNumber {
    public static void main(String[] args) {
        PrintNumber1 p1 = new PrintNumber1();
        PrintNumber2 p2 = new PrintNumber2();
        p1.start();
        p2.start();

    }
}
class PrintNumber1 extends Thread{
    public void run(){
        for (int i = 1;i<=200;i++){
            if(i%2==0){
                System.out.println(i);
            }
        }
    }
}
class PrintNumber2 extends Thread{
    public void run(){
        for (int i = 1;i<=200;i++){
            if(i%2==1){
                System.out.println(i);
            }
        }
    }
}

上述代码运行后会出现两个线程结果交替出现的效果,是多线程的体现。

除了上述创建线程的方式,现实场景中有时会需要临时创建线程,就可以使用匿名对象的方式,以下是代码示例:

java 复制代码
public class Number {
    public static void main(String[] args) {
        //启动两个匿名线程
        new Thread(){
            public void run(){
                for(int i = 0;i<100;i++){
                    if (i%2==0){
                        System.out.println(Thread.currentThread().getName()+"-->"+i);
                    }
                }
            }
        }.start();
        new Thread(){
            public void run(){
                for(int i = 0;i<100;i++){
                    if (i%2!=0){
                        System.out.println(Thread.currentThread().getName()+"-->"+i);
                    }
                }
            }
        }.start();
    }
}

注意事项

  • 不能让已经start()的线程再次执行start(),否则会报异常。

创建线程的方式之二:实现Runnable接口

步骤

  1. 创建一个实现Runnable接口的类
  2. 实现接口中的run()-->将此线程要执行的操作,声明在此方法体中
  3. 创建当前实现类的对象
  4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例
  5. Thread类的实例调用start():1.启动线程2.调用当前线程的run()

代码示例,实现两个线程运行的效果:

java 复制代码
class EvenNumber implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+"-->"+i);
        }
    }
}
public class NumberPrint {
    public static void main(String[] args) {
        EvenNumber e1 = new EvenNumber();
        Thread t1 = new Thread(e1);
        t1.start();
        Thread t2 = new Thread(e1);
        t2.start();
    }
}

部分结果:

使用实现Runnable接口的方式:提供了Runnable接口匿名实现类的匿名对象:

java 复制代码
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println(Thread.currentThread().getName()+"-->"+i);
                }
            }
        }).start();

两种方式对比

  1. 共同点:
  • 启动线程,使用的都是Thread类中定义的start();
  • 创建的线程对象,都是Thread类或其子类的实例
  1. 不同点:一个是类的继承,一个是接口的实现。
  2. 建议:建议使用实现Runnable接口的方式。
    Runnable方式的好处:避免的类的单继承的局限性;更适合处理有共享数据的问题;实现了代码和数据的分离。
相关推荐
我的xiaodoujiao16 分钟前
使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 19--测试框架Pytest基础 3--前后置操作应用
python·学习·测试工具·pytest
dyj09518 分钟前
【Devops-Jenkins自动将Java Maven工程编译成jar、并打成Docker镜像,并上传Harbor】
java·jenkins·devops
lzj_pxxw23 分钟前
嵌入式开发技巧:舍弃标志位,用宏定义函数实现程序单次运行
笔记·stm32·单片机·嵌入式硬件·学习
gordon~926 分钟前
Spring 的bean是安全的吗
java·安全·spring·bean
梵得儿SHI34 分钟前
Java 反射机制实战:对象属性复制与私有方法调用全解析
java·开发语言·java反射机制的实际应用·对象属性复制·反射调用私有方法·私有字段·类型兼容性和敏感字段忽略
带刺的坐椅1 小时前
LangChain4j 比 SolonAI 强在哪?弱在哪?
java·ai·langchain·solon·mcp
江苏世纪龙科技1 小时前
【世纪龙科技】新能源汽车动力电池拆装与检测虚拟实训软件介绍
学习
润 下1 小时前
C语言——回调函数的典型示例(分析详解)
c语言·开发语言·人工智能·经验分享·笔记·程序人生
朝新_1 小时前
【EE初阶 - 网络原理】传输层协议
java·开发语言·网络·笔记·javaee
oak隔壁找我1 小时前
Java 使用技巧与最佳实践
java·后端