博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java实现多线程的两种方式比较及区别
阅读量:6196 次
发布时间:2019-06-21

本文共 5153 字,大约阅读时间需要 17 分钟。

Java实现多线程的两种方式比较及区别

Java实现多线程的方式:2种    方式1:自定义类继承Thread类        1:自定义类MyThread继承Thread类        2:MyThread类里面重写run()方法        3:在测测试类MyThreadTest中创建MyThread类的对象        4:启动线程    方式2:自定义类实现Runnable接口        1:自定义类MyRunnable实现Runnable接口        2:MyRunnable类里面重写run()方法        3:在测测试类MyRunnableTest中创建MyRunnable类的对象        4;在测测试类MyRunnableTest中再创建Thread类的对象,并把3步骤的对象作为构造参数进行传递        5:启动线程            问题:        1:为什么要重写run()方法?            答:run()方法里面封装的是被线程执行的代码。        2:启动线程对象用的是哪个方法?            答:start()方法        3:run()方法和start()方法的区别?            答:run()方法直接调用仅仅是普通方法。           start()方法是先启动线程,再由jvm去调用run()方法。        4:有了方式1,为什么还来一个方式2呢?            答:若自定义类MyThread类已经有一个父类了,那么它就不可以再去继承Thread类了。(java不支持多继承)                若自定义类MyRunnable类已经实现了一个接口了,那么它还可以再去实现Runnable接口。(java支持多实现)                即可以避免由于Java单继承带来的局限性。                                在测试类MyThreadTest中,要想开多个线程,就要先new多个自定义类MyThread的对象,每一个自定义类MyThread的对象的成员变量都相同,这样需要在栈中开辟很多内存;                在测试类MyRunnableTest中,要想开多个线程,只需要new一个自定义类MyRunnable的对象,再new多个Thread类的对象即可,这样就大大节约了内存。                即适合多个相同程序的代码去处理同一个资源的情况,把线程同程序的代码和数据有效分离(即耦合性降低),较好的体现了Java面向对象的设计思想。

注意:图片中 1:为什么药重写run()方法?有个错别字药,应该为要。

示例代码如下:

方式1:自定义类继承Thread类

1 package cn.itcast_02; 2  3 /* 4  * 该自定义的类为什么要重写run()方法? 5  *         自定义类中不是所有的代码都需要被线程执行。 6  *         而这个时候,为了区分哪些代码能够被线程执行,java提供了Thread类中的run()方法,用来包含那些需要被线程执行的代码。 7  *  8  *         注意:这里的  被线程执行 = 开一个新线程执行 9  */10 public class MyThread extends Thread {11     // 不需要被线程执行的代码12     public void show() {13         System.out.println("不需要被线程执行的代码"); // 这么简单的程序去开一个新的线程,纯属浪费啊!14     }15     16     // 需要被线程执行的代码17     @Override18     public void run() {19         // System.out.println("好好学习,天天向上"); // 这么简单的程序去开一个新的线程,纯属浪费啊!20         21         // 一般来说,被线程执行的代码肯定是比较耗时的。22         // 所以这里示例:我们使用循环23         for (int x = 0; x < 1000; x++) {24             System.out.println(x);25         }26     }27 28 }
MyThread.java
1 package cn.itcast_02; 2  3 /* 4  * 需求:我们要实现多线程的程序。 5  *  6  * 如何通过java程序来实现多线程的程序呢? 7  *         由于线程是依赖进程而存在的,所以我们应该先创建一个进程出来。 8  *         而进程是由系统创建的,所以我们应该去调用系统功能创建一个进程。 9  * 10  *         而Java是不能直接调用系统功能的,所以,我们没有办法直接实现多线程程序。11  *         但是呢?Java可以去调用C/C++写好的程序来间接实现多线程程序。12  * 13  *         由C/C++程序去调用系统功能去创建进程,然后由Java进行封装后,这样会产生一些类,我们通过这些类创建的对象去调用他们即可!14  * 15  *         这样我们就可以通过java程序来实现多线程程序了。16  * 17  * 那么Java提供的类是什么呢?18  *         Thread类19  *         通过查看API,我们知道了有2种方式可以实现多线程程序。20  *         (其实有三种方法,第三种明天讲)21  * 22  * 实现多线程程序23  * 方式1:继承Thread类24  *         是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。之后就可以分配并启动该子类的实例了。25  * 步骤26  *         A:自定义类MyThread继承Thread类27  *         B:MyThread类里面重写run()方法28  *         C:在测测试类MyThreadTest中创建MyThread类的对象29  *         D:启动线程30  */31 public class MyThreadTest {32     public static void main(String[] args) {33         // 在测测试类中创建自定义类的对象34         // MyThread my = new MyThread();35         // 启动线程36         // my.run();37         // my.run();38         39         // 调用run()方法为什么是单线程的呢?40         // 因为run()方法直接调用其实就相当于普通的方法调用,所以你看到的是单线程的效果。41         42         // 要想看到多线程的效果,就必须说说另一个方法:start()43         // 面试题:run()和start()的区别?44         // run():仅仅是封装被线程执行的代码,直接调用就是普通方法。45         // start():首先启动了线程,然后再由jvm去调用该线程的run()方法。46         47         // MyThread my = new MyThread();48         // my.start();49         // my.start();50         // IllegalThreadStateException:非法的线程状态异常51         // 为什么呢?因为这个相当于是my线程被调用了两次。而不是两个线程被启动。一个线程不能被多次启动。52 53         // 创建两个线程对象54         MyThread my1 = new MyThread();55         MyThread my2 = new MyThread();56         57         my1.setName("林青霞");58         my2.setName("刘意");59 60         my1.start();61         my2.start();62     }63 }
MyThreadTest.java

方式2:自定义类实现Runnable接口

1 package cn.itcast_05; 2  3 public class MyRunnable implements Runnable { 4  5     @Override 6     public void run() { 7         for (int x = 0; x < 100; x++) { 8             // 由于自定义类实现了接口,所以就不能在自定义类中直接使用Thread类的getName()方法了,但是可以间接的使用。 9             // 间接方法:Thread.currentThread().getName()10             System.out.println(Thread.currentThread().getName() + ":" + x);11         }12     }13 14 }
MyRunnable.java
1 package cn.itcast_05; 2  3 /*  4  * 实现多线程程序 5  * 方式2:实现Runnable接口 6  * 步骤: 7  *         A:在自定义类MyRunnable实现Runnable接口 8  *         B:MyRunnable类里面重写run()方法 9  *         C:在测测试类MyRunnableTest中创建MyRunnable类的对象10  *         D:在测测试类MyRunnableTest中再创建Thread类的对象,并把C步骤的对象作为构造参数进行传递11  *         E:启动线程12  */13 public class MyRunnableTest {14     public static void main(String[] args) {15         // 在测测试类中创建MyRunnable类的对象16         MyRunnable my = new MyRunnable();17 18         // public Thread(Runnable target)19         // 在测测试类中再创建Thread类的对象,并把C步骤的对象作为构造参数进行传递20         // Thread t1 = new Thread(my);21         // Thread t2 = new Thread(my);22         // t1.setName("林青霞");23         // t2.setName("刘意");24 25         // Thread类的方法:26         // public Thread(Runnable target, String name)27         Thread t1 = new Thread(my, "林青霞");28         Thread t2 = new Thread(my, "刘意");29 30         t1.start();31         t2.start();32     }33 }
MyRunnableTest.java

 

我的GitHub地址:
我的博客园地址:
我的蚂蚁笔记博客地址:
Copyright ©2018 黑泽明军
【转载文章务必保留出处和署名,谢谢!】
你可能感兴趣的文章
《微课实战:Camtasia Studio入门精要》——2.4 录制幻灯片
查看>>
《驯服烂代码:在编程操练中悟道》一第2章 按图索骥地编写代码
查看>>
《CCNP安全Secure 642-637认证考试指南》——第2章 网络安全威胁
查看>>
《嵌入式系统开发之道——菜鸟成长日志与项目经理的私房菜》——02-11项目采购/合约管理...
查看>>
Java并发编程之Semaphore(信号量)
查看>>
20 件程序员必须知道的事
查看>>
为什么未来是全栈工程师的世界?
查看>>
《基于ArcGIS的Python编程秘笈(第2版)》——2.7 改变地图范围
查看>>
《UNIX/Linux 系统管理技术手册(第四版)》——1.15 习题
查看>>
《VMware vSphere企业运维实战》——2.4 在VMware ESXi中配置虚拟机
查看>>
《Adobe InDesign CS6中文版经典教程》—第1课1.1节概述
查看>>
明确规范,轻量级标记语言 Markdown 标准化
查看>>
《超越平凡的平面设计:怎样做好版式(第1卷)》—第1章1.4节容易!一个简洁可行的版式...
查看>>
用于 React 的 JS 测试工具 Enzyme
查看>>
《互联网产品设计》一2.7 做一个营销者
查看>>
《HTML5 2D游戏编程核心技术》——第1章,第1.6节本书中使用的JavaScript
查看>>
OC内存管理-OC笔记
查看>>
(NO.00001)iOS游戏SpeedBoy Lite成形记(二十六)
查看>>
sass:常用备忘
查看>>
枚举的一些用法
查看>>