可调用线程 vs. 可运行线程 vs. 继承线程

3
最近我在阅读有关在Java中创建线程的内容,包括通过实现Runnable扩展Thread以及最后一个实现Callable的方式。StackOverflow上的Runnable与Callable比较线程描述了区别,引用到:“两者都是为那些实例有可能被其他线程执行的类而设计的。”这是什么意思?它是否会创建新的线程?如果是的话,为什么我们需要将实现Runnable接口的类传递给Thread构造函数?
此外,我看到创建线程的方法有两种:一种是通过实现Runnable扩展Thread来实现的。在第一种方法中(在找到的教程中),我们需要调用Thread类,该类需要Runnable实例来启动线程。但是,我没有找到类似Callable的东西,因为没有一个Thread构造函数接受Callable。为了运行这些线程,通常使用Executor FrameworkFuture Task。那么,为什么我们说这两种方式是相同的(除了Callable返回值和可以抛出异常)?
最后,要写的是:
Thread t = new Thread();
Thread t1 = new Thread(new RunnableInstance());

这些操作会在系统中创建新线程吗?除了将它作为构造函数传递给 Thread 类,还有其他使用 Runnable 创建新线程的方法吗?

这不应该是一个重复的问题。


1
执行器是Java中创建线程的现代方式,开发人员可以更好地控制线程,并且它具有线程池。使用ExecutorService#submit方法,您可以提交可运行实例。 - Subhrajyoti Majumder
@SubhrajyotiMajumder 谢谢回复。您能回答其他所有问题吗?您的评论只回答了部分问题。 - Vivek Vardhan
3个回答

3

这是什么意思?它会创建新的线程吗?

Callable和Runnable只是接口,它们本身不会创建任何线程。相反,它们为开发人员提供了API和抽象层。当您想要在单独的线程中执行某些代码时,通常会实现Runnable,然后决定如何执行它。它尚未绑定到任何线程。实际上,您有很多选择:

  • 在新线程中执行它
  • 使用某个ExecutorService执行它
  • 或者直接调用它

如果是,为什么需要将实现Runnable的类传递给Thread构造函数?

不需要。 由于Runnable不会在后台创建线程(因为它只是一个接口!),我们需要显式地执行此Runnable。

这些是否会在系统中创建新的线程?

是的。

是否还有其他使用Runnable创建新线程的方法而无需将其作为构造函数传递给Thread类?

是的。我已经提到过ExecutorService。您可以从线程池或完成服务中受益,查看API示例


SO,这意味着我们可以使用任何方法执行实现了 RunnableCallable 接口的类,而不是特定于我在问题中编写的内容。这是真的吗?除了实现了 Callable 接口的类不能在新线程中运行。我是对的吗? - Vivek Vardhan
我又有些困惑了。如果 Runnable 只是一个没有绑定到任何线程的接口,那么它有什么用呢?我们可以有任何接口,比如说 IMyInterface,其中我会有一个 run 方法,然后实现这个接口的任何类都需要将其绑定到新线程中,无论是通过在新线程中执行它还是使用 Executor 服务来执行它。直接运行将在主线程下运行。这正确吗? - Vivek Vardhan
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Vivek Vardhan

1

可调用接口

它将返回执行的结果。

可运行接口

它不会返回任何结果。但是像可调用接口一样独立运行。

继承线程类

它也是一个可运行接口。但如果你继承了线程类,你就不能再继承其他类,因为Java不支持多重继承。


这些也在教程中出现过。我还有一些更具体的问题。 - Vivek Vardhan

1

CallableRunnable提供接口,供其他类在线程中执行它们。它们本身不包含任何功能。最常用的方法是通过ExecutorService实现。可以查看java.until.concurrent中可用的类。那里有很多选项。除非您真的打算添加新的低级线程功能,否则不需要扩展Thread


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接