Java 中创建线程的写法

1、继承 Thread 重写 run

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("hello world");
    }
}
 
public class ThreadDemo {
    public static void main(String[] args) {
        MyThread t = new MyThread();
        t.start();
    }
}

上述就是我们第一个多线程代码,使用多线程打印 “hello world”

这里是第一个创建线程的方式,继承 Thread 类,重写 run 方法!
上述代码中的 t.start(); 这里的工作就是创建了一个新的线程,而这个线程负责执行 t 对象中的 run 方法.

start 方法创建一个新的线程,本质上就是调用操作系统的API,通过操作系统内核创建新线程的 PCB,并且把要执行的指令交给这个 PCB,当 PCB 调度到 CPU 上执行的时候,也就执行到了线程的 run 方法中的代码了!

注意:这里可能有个让人误解的地方,start 方法里是没有调用 run 方法的,start 只是创建了一个线程,由新创建的线程去调用 run 方法!

上述我们代码的执行流程就是:主线程(main线程) 中调用 t.start(); 创建了一个新线程,这个新线程调用 t.run(); 如果 run 方法执行完结束了,这个新的线程也会随之销毁。

start 和 run 的区别

start 方法是真正创建了一个线程(从系统这里创建的),线程是一个独立的执行流.

run 方法只是描述了线程要干什么样的活,如果直接在 main 方法调用 run,此时是不会创建新线程的,这个 run 方法会在 main 线程中执行:

public static void main(String[] args) {
        MyThread t = new MyThread();
        t.run();
}

上述这种情况,只是单纯在 main 线程中执行 t 对象里的 run 方法罢了!

提问:new 一个 Thead 对象是在干嘛呢?

其实也就是创建一个对象罢了,只不过这个对象能够通过 start 方法创建一个线程罢了!

2、实现 Runnable 接口 重写 run

class MyThread implements Runnable {
    @Override
    public void run() {
        System.out.println("hello world");
    }
}
public class ThreadDemo {
    public static void main(String[] args) {
        // 描述一个任务
        Runnable runnable = new MyThread();
        // 把任务交给线程通过 start 方法来执行
        Thread t = new Thread(runnable);
        t.start();
    }
}

上述的 runnable 对象,只是描述了一个任务,这里的写法最主要就是解耦合,目的让线程和线程要干的活之间分离开。

3、使用匿内部类 继承 Thread

public class ThreadDemo {
    public static void main(String[] args) {
        Thread t = new Thread() {
            @Override
            public void run() {
                System.out.println("hello world");
            }
        };
        t.start();
    }
}

这里创建了一个 Thread 的子类,但是是没有名字(匿名)的,Thrad() 后面大括号中表示子类重写父类 Thread 的 run 方法,最后让 t 引用指向该实例。

4、使用匿名内部类 实现 Runnable

public class ThreadDemo {
    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello world");
            }
        });
        t.start();
    }
}

这样的写法本质上和上一个写法相同,此处只是创建了一个匿名内部类,实现了 Runnable 接口重写了 run 方法,同时创建了类的实例,把这个匿名的 Runnable 对象作为参数传递给了 Thread 的构造方法。

5、使用 Lambda 表达式

public class ThreadDemo {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            System.out.println("hello world");
        });
        // Thread t = new Thread(() -> System.out.println("hello world")); 等价上面
        t.start();
    }
}

此处是通过 Lambda 表达式来描述任务,直接把 Lambda 传给 Thread 构造方法,这里跟上种方法没有啥区别,只是语法的不同而已,因为 Runnable 这个接口就是一个函数式接口,才能使用这种语法,具体内容见 Lambda 章节。

上述介绍的几种写法,离不开 Thread 类,只不过是使用了不同的方法来描述 Thread
里的任务是啥,只是语法规则的不同,本质上都是一样的方法,这些方法创建出来的线程都是一样的,随着后面学习的深入,会见识到其他创建线程的方法但大体都是大同小异。

原文链接:https://blog.csdn.net/m0_61784621/article/details/128955102

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值