【并发编程】创建线程运行时代码的 3 种方式

本文详细介绍了在Java中创建线程的三种方式:继承Thread类、实现Runnable接口以及实现Callable接口。重点讨论了Runnable和Callable接口的区别,以及线程池的应用。建议通常使用实现Runnable接口,因其更适合线程池场景。同时,强调了启动线程时调用start而非run的重要性,以及如何设置和获取线程名。
摘要由CSDN通过智能技术生成

在 java 中,创建线程运行时代码的方式有 3 种:

  1. 继承 Thread 类,覆写其 run 方法;
  2. 实现 Runnable 接口,实现 run 方法,Thread 类也实现了 Runable 接口;
  3. 实现 Callable 接口,实现其 call 方法,这种方式是在 JDK1.5 中的 java 并发包中引入的;

一个很常见的错误是,把创建线程运行时代码创建线程混为一谈。

在这里先给出一个结论:
创建线程的方式只有一种,就是创建 Thread 对象的实例,创建线程运行时代码就是以上的 3 种方式。

对于 Runnable 和 Callable 接口,主要就是为了实现接口中定义的方法,以便线程执行时回调,而实现的方法中的具体内容,就是我们所说的线程运行时代码。

对于 Thread,其本身是一个线程对象,不过由于其也实现了 Runnable 接口,因此其本身是将创建线程对象和线程运行时代码合为一体了。

一旦线程启动后 start 方法就会立即返回,而不会等待到 run 方法执行完毕才返回。

Callable 接口与 Runnable 接口类似,其定义了一个 call 方法,不同的是,它可以返回运行的结果。

public interface Callable<V> {
    V call() throws Exception;
}

泛型参数 V 就是返回值的类型,Callable 接口需要与线程池结合使用。

选择创建Thread子类还是选择实现Runnable接口?

对于这两种方式哪种好并没有一个确定的答案,它们都能满足要求。

就我个人意见,我更倾向于实现Runnable接口这种方法。

因为 java 中有一个线程池的概念。所谓线程池,可以理解为有一堆线程对象已经创建好了,那么其缺的就是线程运行时代码。所以我们只需要提供了运行时代码就好了,因此实现 Runable 接口可能是更好的一种方式。

常见错误:启动线程时调用了 run 方法而非 start 方法

起初你并不会感觉有什么不妥,因为 run 方法确实被执行了。
但事实上,执行方法的是当前线程,并没有创建新线程。
start 方法才会启动一个新的线程,并分配相应的资源,例如栈内存空间,最后回调线程的运行时代码

线程名
当创建一个线程的时候,可以给线程起一个名字,它有助于我们区分不同的线程,帮助我们很好地排查问题。

MyRunnable runnable = new MyRunnable();
Thread thread = new Thread(runnable, "New Thread");
thread.start();
System.out.println(thread.getName());

需要注意的是,因为 MyRunnable 并非 Thread 的子类,所以 MyRunnable 类并没有 getName 方法。可以通过以下方式得到当前线程的引用:

Thread.currentThread();

因此,通过如下代码可以得到当前线程的名字:

String threadName = Thread.currentThread().getName();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值