Java线程实现方式详解(Java基础)

网友投稿 645 2022-05-30

你好我是辰兮,很高兴你能来阅读,本篇为Java基础之多线程的实现讲解,基础知识的讲解,相关的更多,面试知识已经提前整理好文章可以阅读学习,希望对初学者有帮助。

Java线程的实现方式详解(Java基础)

线程进程基础知识参考: 进程线程的面试问题小结

线程面试常见问题参考: Java常见多线程基础面试问题

文章目录

一、文章序言

二、继承Thread类

三、实现Runnable接口

四、两种实现方式的比较

五、调用start()与run()方法的区别

一、文章序言

创建线程的方式一致为Java面试常见基础问题,基础学习中我们常用前两种方式,下文带大家用代码案例进一步了解相关的知识。

常用第二种接口实现,因为实现接口的方式比继承类的方式更灵活,也能减少程序之间的耦合度。

二、继承Thread类

继承自Thread类,Thread类是所有线程类的父类,实现了对线程的抽取和封装

继承Thread类创建并启动多线程的步骤:

①.定义一个类,继承自Thread类,并重写该类的run方法,该run方法的方法体就代表了线程需要完成的任务,因此,run方法的方法体被称为线程执行体

②.创建Thread子类的对象,即创建了子线程

③.用线程对象的start方法来启动该线程

Demo先创建一个售票线程

package demo1; public class SellTickets extends Thread { //共享数据 static int count = 100; @Override public void run() { //循环售票 while(count > 0) { count--; System.out.println(Thread.currentThread().getName() + "售出了一张票,剩余" + count); } } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

测试类

import demo1.SellTickets; public class TheadDemo { public static void main(String[] args) { //模拟四个售票员售票 SellTickets s1 = new SellTickets(); SellTickets s2 = new SellTickets(); SellTickets s3 = new SellTickets(); // System.out.println(s1.currentThread().getName()); //这个线程的名称是main s1.start(); s2.start(); s3.start(); } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

三、实现Runnable接口

实现Runnable接口创建并启动多线程的步骤:

a.定义一个Runnable接口的实现类,并重写该接口中的run方法,该run方法的方法体同样是该线程的线程执行 体

b.创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象

c.调用线程对象的start方法来启动该线程

继续售票的案例 应该是继承implement接口,为了简洁我写一个里面了

package demo1; public class SellTickets { static int count = 100; static Runnable r = new Runnable() { @Override public void run() { while(count > 0) { count--; System.out.println(Thread.currentThread().getName() + "售出了 一张票,剩余" + count); } } }; public static void main(String[] args) { Thread t1 = new Thread(r); Thread t2 = new Thread(r); Thread t3 = new Thread(r); t1.start(); t2.start(); t3.start(); } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

四、两种实现方式的比较

①实现Runnable接口的方式

a.线程类只是实现了Runnable接口,还可以继承其他类【一个类在实现接口的同时还可以继承另外一个类】

b.可以多个线程共享同一个target对象,所以非常适合多个线程来处理同一份资源的情况

c.弊端:编程稍微复杂,不直观,如果要访问当前线程,必须使用Thread.currentThread()

② 继承Thread类的方式

a.编写简单,如果要访问当前线程,除了可以通过Thread.currentThread()方式之外,还可以使用 super关键字

b.弊端:因为线程类已经继承了Thread类,则不能再继承其他类【单继承】 实际上大多数的多线程应用都可以采用实现Runnable接口的方式来实现【推荐使用匿名内部类】java类是单知继承的

五、调用start()与run()方法的区别

Thread thread = new Thread(); thread.start();

1

2

① - start()方法会新建一个线程,并且让这个线程执行run()方法。

Thread thread = new Thread(); thread.run();

1

2

② - 调用run()也能正常执行。但是,却不能新建一个线程,而是在当前线程中调用run()方法,只是作为一个普通的方法调用。

我知道这样表达有点抽象,所有我截图了上述案例

建议:不要用run()来开启新线程,它只会在当前线程中,串行执行run()方法中的代码。

拓展一下源码的学习只截取了部分

public synchronized void start() { private native void start0(); /** * If this thread was constructed using a separate * Runnable run object, then that * Runnable object's run method is called; * otherwise, this method does nothing and returns. *

* Subclasses of Thread should override this method. * * @see #start() * @see #stop() * @see #Thread(ThreadGroup, Runnable, String) */ @Override public void run() { if (target != null) { target.run(); } } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

在start方法里调用了一次start0方法,这个方法是一个只声明未定义的方法,并且使用了native关键字进行定义native指的是调用本机的原生系统函数。所以,调用start方法,会告诉JVM去分配本机系统的资源,才能实现多线程。

The best investment is to invest in yourself

2020.05.29 记录辰兮的第70篇博客

Java 任务调度

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Google Earth Engine ——MERIT/DEM/v1_0_3影像100M分辨率数据集
下一篇:Hadoop分布式集群搭建-5节点(HA 高可用)
相关文章