多线程1(面试题--常见的线程创建方式)

1.创建子类,继承Thread,重写run方法

2.创建子类,实现Runnable接口,重写run方法

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

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

5.lambda表达式(推荐)


继承Thraed重写run

步骤:继承->重写->实例->启动

缺点:线程和任务绑定在一起

java 复制代码
//1.继承
class MyThread extends Thread{
    //2.重写

    @Override
    public void run() {
        while (true){
            System.out.println("hello thread");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    }
}
public class Demo1 {
    public static void main(String[] args) throws InterruptedException {
        //MyThread thread = new MyThread();

        //3.实例
        Thread thread = new MyThread();

        //4.启动
        thread.start();

        while (true){
            System.out.println("hello main");
            Thread.sleep(2000);
        }
    }
}

实现Runnable重写run

步骤其实大差不差,区别在于,不仅要实例化Thread对象,还要实例化Runnable对象,将Runnable对象作为参数传给Thread

通俗一点来说就是,Runnable是单独描述线程要执行的任务的,此时与线程没关系,将其作为参数传给Thread就是告诉线程所要执行的任务是什么,两者之间解耦合度更高,而第一种方法是将线程和任务绑定在了一起,耦合度更高

java 复制代码
class MyRunnable implements Runnable{

    @Override
    public void run() {
        while (true){
            System.out.println("hello thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
public class Demo2 {
    public static void main(String[] args) throws InterruptedException {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);

        thread.start();

        while (true){
            System.out.println("hello main");
            Thread.sleep(1000);
        }
    }
}

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

本质上跟第一种方法没区别,只不过使用了匿名内部类来创建线程,好处就在于这个类是一次性的,只使用一次,也就是跟着当前线程一起,线程结束,类也结束

java 复制代码
public class Demo3 {
    public static void main(String[] args) throws InterruptedException {
        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");
            Thread.sleep(1000);
        }
    }
}

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

java 复制代码
public class Demo4 {
    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表达式

这是更推荐的一种做法,更加简洁

java 复制代码
public class Demo5 {
    public static void main(String[] args) {
        //lambda
        Thread thread = new Thread(()->{
           while (true){
               System.out.println("hello thread");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
           }
        });
        thread.start();

        while (true){
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

使用lambda表达式需要注意的是变量捕获的情况:final 事实final(没有被修改的变量)


问题:为什么在继承或实现Runnable的时并不需要导包呢?

是因为他们都属于lang包底下,在Java中,lang包会默认导入到项目中,因此不需要手动import

这是基于管理方便的缘故,用什么类就导入什么包,但也存在这种方便的,默认自动导入的lang包

相关推荐
SL_staff1 小时前
规则联动:给工厂装上‘自动化神经反射弧’——JVS·物联网平台规则引擎实战教程
java·人工智能·物联网
骑着蜗牛撵大象3271 小时前
Linux 进程间通信之管道:从 pipe() 的内核语义到 FIFO 落地排错
android·java·linux·系统编程·fifo·管道·进程间通信
WJ.Polar1 小时前
Java封装、继承、多态
java·开发语言
ly76891 小时前
PostgreSQL 备份恢复策略:pg_basebackup、WAL 归档与 PITR 在企业 Java 系统中的落地
java·数据库·postgresql·pitr·pg_basebackup·wal 归档
摇滚侠1 小时前
Java 中如何表示负数,有符号和无符号的区别,补码的计算规则,char byte short int long 的范围
java·开发语言
weixin_307779132 小时前
C++代码实现MATLAB中的fitrtree函数功能
开发语言·c++·算法·matlab
桃桃乌龙_2 小时前
LangGraph 深度解析:从链到图,把 Agent 的循环画出来
面试
奇牙coding2 小时前
Codex CLI 升级后多文件编辑静默失效:config.yaml 枚举变更排查与修复指南
java·前端·javascript·ai
爱读书的小胖2 小时前
Codewars:Rot13(C)解题分析
c语言·开发语言
小羊没烦恼!2 小时前
Ajax与JSON的一些总结
android·java·前端·数据库·mysql·算法·okhttp