java中创建线程的4种方式

article/2025/9/17 0:01:29

写在前面的话

java线程创建方式有几种?这种问题在面试中经常被问到,你可能心里马上反映出两种方式(实现Runnable、继承Thread),当你把这两种叙述给面试官听后,面试官会觉得你该掌握的知识已经有了,但是仅仅而已。如果你还说了callable与future、线程池,那么面试官就会认为你 知识覆盖面广,对你好感加一!下面首先叙述为什么会出现线程,以及线程在实际生活中的例子,紧接着给出四种创建线程的方式,加以代码进行演示。喜欢博主文章的你,动动你们的小爪子,点赞收藏呗(#^.^#)

1、线程的知识

1.1、什么是多线程

百度百科这样说:多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。好像和没说一样,概念还是不怎么理解。那就举个例子:早上小明起床后,需要完成刷牙、洗脸、烧水、听广播,为了节约时间、提高效率,小明边烧水、边听广播、边刷牙洗脸,这三个任务并行进行,就类似于三个线程。多线程就是同时多个线程同时工作,并发执行任务。

1.2、为什么会有多线程

这个问题可以转换为:多线程带来了什么好处与优势。结合《JAVA并发编程实践》总结如下:

1、发挥多处理器的强大能力

现在的处理器在频率上的提升空间越来越小,为了增加设备整体的性能,出现了多核多处理器设备。由于线程是cpu调度的基本单位, 当一个程序中只有一个线程时,最多只能在一个CPU上进行运行,其他CPU将处于空闲状态,严重影响多核CPU的性能。因此,如果涉及合理正确的多线程程序,将会充分利用多核CPU性能优势,提高整体设备性能。

2、建模的简单性

通过使用线程,可以将复杂并且异步的工作流进一步分解为一组简单并且同步的工作流,每个工作流在一个单独的线程中运行,并在特定的同步位置进行交互。我们可以通过一些现有框架来实现上述目标,例如Servlet和RMI,框架负责解决一些细节问题,例如请求管理、线程创建、负载平衡,并在正确的时候将请求分发给正确的应用程序组件。编写Servlet的开发人员不需要了解多少请求在同一时刻要被处理,也不需要了解套接字的输入流或输出流是否被阻塞,当调用Servlet的service方法来响应Web请求时,可以以同步的方式来处理这个请求,就好像它是一个单线程程序。

3、异步事件的简化处理

服务器应用程序在接受多个来自远程客户端的套接字连接请求时,如果为每个连接都分配其各自的线程并且使用同步I/O,那么就会降低这类程序的开发难度。如果某个应用程序对套接字执行读操作而此时还没有数据到来,那么这个读操作将一直阻塞,直到有数据到达。在单线程应用程序中,这不仅意味着在处理请求的过程中将停顿,而且还意味着在这个线程被阻塞期间,对所有请求的处理都将停顿。为了避免这个问题,单线程服务器应用程序必须使用非阻塞I/O,但是这种I/O的复杂性要远远高于同步I/O,并且很容易出错。然而,如果每个请求都拥有自己的处理线程,那么在处理某个请求时发生的阻塞将不会影响其他请求的处理。

4、响应更灵敏的用户界面

GUI界面采用多线程,可以同时响应多个按钮,比如在IDEA中,在程序运行时,还可以继续进行程序编写。

1.3、线程与进程的区别

进程是操作系统进行资源分配的单元,线程是CPU调度运行的单位;一个进程中可以包含很多线程,线程共享进程的内存等资源;每个进程拥有各自独立的一套变量,相互不影响,而线程则共享数据,会存在线程安全问题。

1.4、举例说明线程与进程

为了能够看到本地计算机上的线程信息,下载Process Explorer,解压运行进行查看。

 从上图可以形象的验证,进程与 线程之间的关系。关于Process Explorer的用法,感兴趣的可以自行研究。

2、java创建线程的四种方式

2.1、实现Runnable

通过实现Runnable接口,重写run()方法。然后借助Thread的start()方法开启线程,调用run()方法是不会开启新线程的,只是一次方法调用而已。

看一下Runnable接口的java代码,发现它只有一个run()方法。

public interface Runnable {/*** When an object implementing interface <code>Runnable</code> is used* to create a thread, starting the thread causes the object's* <code>run</code> method to be called in that separately executing* thread.* <p>* The general contract of the method <code>run</code> is that it may* take any action whatsoever.** @see     java.lang.Thread#run()*/public abstract void run();
}

进行线程编写, 

public class CreateThreads implements Runnable{@Overridepublic void run() {System.out.println("通过实现Runnable接口开启线程~");}public static void main(String[] args) {CreateThreads createThreads = new CreateThreads();Thread thread = new Thread(createThreads);thread.start();}
}

2.2、继承Thread

继承Thread类,重写run()方法。

public class CreateThreads extends Thread{@Overridepublic void run() {System.out.println("通过继承Thread开启线程~");}public static void main(String[] args) {CreateThreads createThreads = new CreateThreads();Thread thread = new Thread(createThreads);thread.start();}
}

注意:继承Thread类,重写run()方法,其本质上与实现Runnable接口的方式一致,因为Thread类本身就实现了Runnable接口

public class Thread implements Runnable 。再加上java中多实现,单继承的特点,在选用上述两种方式创建线程时,应该首先考虑第一种(通过实现Runnable接口的方式)。

2.3、通过Callable、Future

通过Runnable与Thread的方式创建的线程,是没有返回值的。然而在有些情况下,往往需要其它线程计算得到的结果供给另外线程使用( 例如:计算1+100的值,开启三个线程,一个主线程,两个计算线程,主线程需要获取两个计算线程的结算结果(一个计算线程计算1+2+...+50,另外一个线程计算51+52+..+100),进行相加,从而得到累加结果),这个时候可以采用Runnable与Thread的方式创建的线程,并通过自行编写代码实现结果返回,但是不可避免的会出现黑多错误和性能上的问题。基于此,JUC(java.util.concurrent)提供了解决方案,实现Callable的call()方法(这个类似Runnable接口),使用Future的get()方法进行获取。

下面首先看一下Callable接口:

public interface Callable<V> {/*** Computes a result, or throws an exception if unable to do so.** @return computed result* @throws Exception if unable to compute a result*/V call() throws Exception;
}

下面开始使用Callable、与Future创建多线程。创建过程为:1、自定义一个类实现Callable接口,重写call()方法;2、使用JUC包下的ExecutorService,生成一个对象,主要使用submit()方法,返回得到Future对象(关于JUC包下的诸如ExecutorService解析使用,请关注博主的后序文章);3、采用Future的get()获取返回值。

import java.util.concurrent.*;/*** @author wolf* @create 2019-04-25    14:53* 计算1+...+100的结果,开启三个线程,主线程获取两个子线程计算的结果,一个子线程计算1+...+50,一个子线程计算51+...+100。*/
public class CreateThreads implements Callable {public static void main(String[] args) throws ExecutionException, InterruptedException {//生成具有两个线程的线程池ExecutorService executorService = Executors.newFixedThreadPool(2);//调用executorService.submit()方法获取FutureFuture<Integer> result1 = executorService.submit(new CreateThreads());Future<Integer> result2 = executorService.submit(new SubThread());//使用Future的get()方法等待子线程计算完成返回的结果int result = result1.get() + result2.get();//关闭线程池executorService.shutdown();//打印结果System.out.println(result);}//子线程1,用来计算1+...+50@Overridepublic Object call() throws Exception {int count = 0;for (int i = 1; i <= 50; i++)count = count + i;return count;}
}class SubThread implements Callable {//子线程2,用来计算51+...+100@Overridepublic Object call() throws Exception {int count = 0;for (int i = 51; i <= 100; i++)count = count + i;return count;}
}

2.4、通过JUC里面的线程池

JUC并发包里的 Executors工具类,提供了创建线程池的工厂方法,具体可以参看JDK的API。

下面就Executors.newFixedThreadPool()说明,这里请移步2.3节的程序,会发现其实2.3节已经使用了Executors.newFixedThreadPool(2)构建线程池。

 

3、总结

通过上述叙述,希望对你知识掌握和面试有所帮助。多线程是java中的进阶,这一块还有很多知识点,本文后会继续发布关于多线程博客,旨在介绍java中多线程的框架,介绍JUC包,一起学习共勉。文中有错误的地方,还请留言给予指正,不胜感激~最后,喜欢博主的文章不妨关注点赞收藏哦,方便下次不走错门。


http://chatgpt.dhexx.cn/article/5sCTVpWp.shtml

相关文章

【 java 多线程】创建多线程的方式四:使用线程池创建多线程

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

创建线程的方式

一般来说&#xff0c;创建线程有三种方式&#xff1a;继承 Thread 类、实现 Runnable 接口和实现 Callable 接口。 继承 Thread 类&#xff1a;继承 Thread 类&#xff0c;重写 run() 方法&#xff0c;调用 start() 方法启动线程。 public class MyThread {public static cla…

【JAVAEE】创建线程的方式及线程的常用方法

目录 1.创建线程的四种方式 1.1继承Thread类 1.2实现Runnable接口 1.3匿名内部类 1.4lambda表达式 2.多线程的优势-增加运行速度 3.Thread类及常用方法 3.1构造方法 3.2常见属性 演示后台线程 演示线程是否存活 3.3线程中断 3.4线程等待-join() 3.5获取当前线程 …

创建线程的方式有那些?

目录 一.创建线程的4种方式 二.创建线程方式有什么区别&#xff1f; 一.创建线程的4种方式 &#xff08;1&#xff09;写一个类继承Thread&#xff0c;覆盖重写run方法 &#xff08;2&#xff09;创建一个Runnable类型的对象,实现run()方法,传入Thread的构造方法中 &#x…

创建线程几种方式

创建线程的几种方式&#xff1a; 方式1&#xff1a;通过继承Thread类创建线程 步骤&#xff1a;1.定义Thread类的子类&#xff0c;并重写该类的run方法&#xff0c;该方法的方法体就是线程需要执行的任务&#xff0c;因此run()方法也被称为线程执行体 2.创建Thread子类的实例&a…

线程创建的四种方式

java中创建线程的四种方法以及区别 Java使用Thread类代表线程&#xff0c;所有的线程对象都必须是Thread类或其子类的实例。Java可以用四种方式来创建线程&#xff0c;如下所示&#xff1a; 1&#xff09;继承Thread类创建线程 2&#xff09;实现Runnable接口创建线程 3&am…

四种线程创建方式

一. 继承Thread类 继承Thread类创建线程的步骤: 创建一个自定义类继承Thread类,重写run()方法,将所要单独线程运行写入run()方法中;创建Thread类的子类的对象;调用该对象的start()方法,该start()方法表示开启线程,然后调用执行run方法; Testpublic void test() {Thread.curre…

创建线程的四种方式

我们创建线程池一般有四种方式&#xff0c;分别是&#xff1a; 1.继承Thread类&#xff0c;重写run()方法&#xff1b; 2.实现Runnable接口&#xff0c;重写run()方法&#xff1b; 3.实现Callable接口&#xff0c;重写call()方法&#xff1b; 4.使用线程池创建线程&#xff1b;…

线程创建常用的四种方式

java中创建线程的四种方法以及区别 Java使用Thread类代表线程&#xff0c;所有的线程对象都必须是Thread类或其子类的实例。Java可以用四种方式来创建线程&#xff0c;如下所示&#xff1a; 1&#xff09;继承Thread类创建线程 2&#xff09;实现Runnable接口创建线程 3&…

银行测试核心项目之测试阶段分享

最近有小伙伴说「想了解核心系统建设中&#xff0c;冒烟、SIT、UAT、回归测试的重点&#xff0c;如何设计测试案例&#xff0c;或相关的资料推荐等」。 这个话题很笼统&#xff0c;测试这一块儿除了业务测试&#xff0c;还有性能测试、安全测试等&#xff1b;以及不同的角色对…

金融银行测试面试题分享

1、网上银行转账是怎么测的&#xff0c;设计一下测试用例。 回答思路&#xff1a; 宏观上可以从质量模型&#xff08;万能公式&#xff09;来考虑&#xff0c;重点需要测试转账的功能、性能与安全性。设计测试用例可以使用场景法为主&#xff0c;先列出转账的基本流和备选流。…

2022年软件测试——精选金融银行面试真题

前言 小伙伴们好久不见呀&#xff0c;现已经到了八月份了过了这一个月就是金九银十了&#xff0c;在这里呢笔者给大家准备了一份软件测试金融方面的面试题&#xff0c;笔者在这里就不多说废话了哟&#xff0c;咱们直接进入正题哈。 1、P2P你们也测试后台管理吗&#xff1f;个人…

金融行业软件测试

金融行业软件测试 一、什么是金融行业二、金融行业的业务特点1. 金融行业的业务特点 三、金融行业测试主要测试范围1. 功能测试2. 业务验证测试3. 客户端测试4. 接口测试5. 性能测试6. 安全性测试 四、金融行业软件测试的现状五、第三方测试的优点 一、什么是金融行业 金融业是…

走出新手村,软件测试银行项目怎么测试 + 面试题(答案)

前言 业务&#xff1a; 银行类app具体模块业务讲解&#xff1a; 掌上生活&#xff08;消费/理财&#xff09; 消费&#xff1a; 与电商平台业务类似 饭票&#xff1a;GPS定位城市服务、饭票购买消费、餐厅查询、代金券、周三五折、banner图、我的饭票、我的抵扣券 影票 …

【工作总结】银行软件测试工作总结

最近换工作进入到外包公司&#xff0c;驻点到银行进行集成测试工作&#xff0c;为了让自己更熟悉金融行业&#xff0c;特别是银行业相关业务&#xff0c;以及总结自己测试的一些经验&#xff0c;希望将自己了解和学习的内容记录下来。主要从以下几个方面学习&#xff1a; 一、…

大咖or学员?金融银行软件测试案例分享!

2019年4月14日汇智动力学院在成都校区开展了本年度的第一次线下技术交流沙龙&#xff08;银行金融测试方向&#xff09;&#xff1b; 刘德宝老师做技术分享 通过在上个月末举办的老学员周末娱乐活动&#xff08;雀圣大赛&#xff09;&#xff0c;我们做了一系列的问卷调查&…

银行软件测试面试问题

测试技术面试题 1、什么是兼容性测试&#xff1f;兼容性测试侧重哪些方面&#xff1f; 参考答案&#xff1a; 兼容测试主要是检查软件在不同的硬件平台、软件平台上是否可以正常的运行&#xff0c;即是通常说的软件的可移植性。 兼容的类型&#xff0c;如果细分的话&#x…

浦发银行软件测试面试真题(小编面试亲测)

对于想要面试去银行面试的小伙伴们看过来&#xff0c;今天为大家总结了浦发银行的面试题&#xff0c;其实很多面试题很多公司都差不多。主要看自己如何灵活回答。以下的问题小编盆友之前面试非浦发银行的银行项目也有被问到过&#xff0c;是在一面的时候被问到的。答案仅作为参…

金融银行软件测试超大型攻略,最受欢迎的金融银行大揭 秘附面试题

零、为什么做金融类软件测试 举个栗子&#xff0c;银行里的软件测试工程师。横向跟互联网公司里的测试来说&#xff0c;薪资相对稳定&#xff0c;加班少甚至基本没有&#xff0c;业务稳定。实在是测试类岗位中的香饽饽&#xff01; 一、什么是金融行业 金融业是指经营金融商…

银行软件测试简历模板,找工作的小伙伴看过来了

目录 目录 个人简历 教育背景 工作经历 自我评价 专业技能 ​编辑 个人简历 姓  名&#xff1a; 性  别&#xff1a; 学  历&#xff1a; 经  验&#xff1a; 手  机&#xff1a; 邮  箱&#xff1a; 政治面貌&#xff1a; 意向岗位&#xff1a; 软…