长篇干货建议收藏—话说java多线程那些事儿.docx

上传人:A*** 文档编号:141583613 上传时间:2020-08-10 格式:DOCX 页数:32 大小:3.76MB
返回 下载 相关 举报
长篇干货建议收藏—话说java多线程那些事儿.docx_第1页
第1页 / 共32页
长篇干货建议收藏—话说java多线程那些事儿.docx_第2页
第2页 / 共32页
长篇干货建议收藏—话说java多线程那些事儿.docx_第3页
第3页 / 共32页
长篇干货建议收藏—话说java多线程那些事儿.docx_第4页
第4页 / 共32页
长篇干货建议收藏—话说java多线程那些事儿.docx_第5页
第5页 / 共32页
点击查看更多>>
资源描述

《长篇干货建议收藏—话说java多线程那些事儿.docx》由会员分享,可在线阅读,更多相关《长篇干货建议收藏—话说java多线程那些事儿.docx(32页珍藏版)》请在金锄头文库上搜索。

1、长篇干货,建议收藏话说java多线程那些事儿1、线程和进程的区分一个进程中包含多个线程,一个进程就相当于一个应用程序,一个应用程序底层就是cpu来运行的,比如我们的电脑同时打开了多个应用,表面看来像是在同时运行,实际上在同一时间只运行了一个应用程序,只不过cpu的运行速度非常快,会进行高速切换,让我们觉得是在同时进行。最经典的一个例子就是迅雷了,我们电脑打开迅雷相当于开了一个进程,当我们使用迅雷下载东西的时候,比如说,下载两部电影,那么在迅雷中就存在两个不同的执行路径,也就是有两个线程在同时做下载工作。所以,进程包含线程,相当于所有线程的集合。一个线程就是一个执行路径。为什么要用多线程?多线程

2、的好处就是提高程序的效率。但是可能会影响性能。main是主线程,我们创建的线程叫做子线程,如果说一个项目中肯定有一个线程,那么这个线程就是主线程了。对于这个问题,到底该怎么理解或者说区分线程和进程的概念,再举一个非常贴切的例子,我们大多数人都用过扣扣吧,我们打开一个扣扣,其实就是开启了一个进程,然后我们发送一段文字,那就是开启了一个线程,我们再发送一天语音,那就是又开启了一个线程,那么在这个扣扣的进程中就有发文字和语言两个线程了,当然,可能还有其他的线程!在知乎上有这么一个帖子,就是区分线程和进程的额,回答的也不少,可以看看线程和进程的区别是什么?那么,关于进程和线程的区别问题就到这!2、多线

3、程的创建方式学习多线程,最基本的就是要会创建多线程了,常规来说创建多线程的方式应该有三种1. 继承Thread类2. 实现Runnable接口3. 匿名内部类在此之前很有必要说一下这个main,也就是在写Java程序中经常见到的主线程,代码表现形式就是 public static void main(String args) do. 这个main叫做主线程,是程序的入口,而且是由jvm也就是Java虚拟机创建的。下面具体说一下创建线程的三种方式首先是继承自Thread类的方式,看代码/* * 创建线程的我第一种方式 * 继承自Thread类 */class A extends Thread O

4、verride public void run() System.out.println(正在执行线程A。); 以上就是使用继承自Thread类的方式创建线程,这里的Thread实际上是实现了Runnable接口再看这个Runnable接口因此,使用继承Thread类的方式创建线程需要实现run方法,实际的逻辑处理也是在这个run方法中实现的再看第二种创建线程的方式就是实现Runnable接口的方式,同样,先来看代码/* * 创建线程的第二种方式 * 实现Runnable接口 */class B implements Runnable Override public void run() Sy

5、stem.out.println(正在执行线程B、); 之前就说过,Runnable接口中有一个抽象run方法,所以,对于实现Runnable接口的方式也是需要实现run方法的,同样的逻辑处理也是在run中,接下来看最后一种创建线程的方式,通过匿名内部类的方式。 public static void main(String args) System.out.println(主线程在执行、); /* * 线程创建的第三种方式 * 匿名内部类 */ new Thread(new Runnable() Override public void run() System.out.println(匿名内

6、部类执行的线程); ).start(); 这里要注意,匿名内部类是要写在方法之中的,这里写在主方法中,可以看到,这个线程是通过新建一个Thread对象,然后在传入一个Runnable,之后也是实现Run方法,然后调用线程的start方法即可开启此线程在最后一种使用匿名内部类的方式创建线程中调用了start开启线程,那么,对于其他两种创建线程的方式该如何启动线程呢? /执行线程B B b = new B(); Thread thread = new Thread(b); thread.start(); /执行线程A A a = new A(); a.start();可以看到,都是调用线程对象的s

7、tart方法从而开启线程,这里有些人会有些疑问,我们随便看一个/* * 创建线程的我第一种方式 * 继承自Thread类 */class A extends Thread Override public void run() System.out.println(正在执行线程A。); 就拿这个线程来说,为什么不可以这样也就是说在线程对象中是有一个run方法的,为什么执行线程不可以直接调用这个run方法呢?而要调用start开启线程呢?其实也很好理解,如果直接调用run方法的情况下,那么这跟平常的类又有什么区别呢?要知道线程是独立的额一个线程,如果直接调用run方法的话不就等同于直接执行这个方法

8、,就类似一个普通的类,然后调用它的一个方法似的,可是,这里可是线程啊。说的官方一点,对于线程而言,有一个线程规划器的概念,可以理解为就是专门管理线程执行的一个玩意,只有当你调用start,才会将这个线程交给线程规划器去管理,只有交给了线程规划器,才能真正算得上是一个线程,否则,就是一个普通的类。而非线程。以上说了创建线程的三种方式,那么,到底使用哪种比较好呢?实际情况中可能使用实现Runnable接口的方式可能多一点,为什么呢?也很简单,因为在Java中,类只能是单继承的,所以如果使用继承Tread类的方式的话就不能再继承自其它的类了,这在实际的开发中势必会带来一些局限性,但是使用实现Runn

9、able接口的方式就可以避免这一局限性,因为接口是支持多实现的,而且还可以再继承其它的类,这样的话,灵活性就高出很多。到此要知道的几个知识点1. 创建线程的三种方式2. 为什么不调用run3. 使用哪种创建线程的方式更好,为什么再续3、线程常用的API先来看一段代码在这段代码中,跟之前写的创建线程代码没什么区别,就是在打印的时候添加了一个Thread.currentThread().getName()很好理解,就是得到当前线程的名称的,看输出结果平常在开发当中,如果需要得知当前线程就可以使用此方法来获得当前线程的名称。下面再介绍另外一个方法:isAlive()这个方法是用来判断当前线程是否处于

10、活动状态,那么首先需要知道什么是“活动状态”所谓的活动状态就是线程已经启动且尚未停止,根据这个理解,看一段代码,以一个线程为例/* * 创建线程的第一种方式 * 继承自Thread类 */class A extends Thread Override public void run() System.out.println(正在执行线程A。+Thread.currentThread().getName(); System.out.println(线程的活动状态是:+Thread.currentThread().isAlive(); 然后执行 /执行线程A A a = new A(); Syst

11、em.out.println(此时线程的状态是:+Thread.currentThread().isAlive(); a.start(); System.out.println(此时线程的状态是:+Thread.currentThread().isAlive();重点看一下执行结果对照着代码再看执行结果,能够看出对于线程a来说只有当调用了start方法,线程才开始执行,也就是处于活动状态。此外还有一个比较熟悉的方法就是sleep(),是让线程暂时休眠的一个方法,这里要注意的是是让当前正在执行的线程暂停执行,下面看一个具体的例子 /执行线程A A a = new A(); a.start();

12、System.out.println(System.currentTimeMillis(); try Thread.sleep(2000); System.out.println(System.currentTimeMillis(); catch (InterruptedException e) e.printStackTrace(); 代码当中添加了以下代码来让线程休眠2秒hread.sleep(2000);然后看打印输出结果线程在执行的过程中暂停了2000毫秒也就是2秒钟的时间,这在平常的开发中也有一些特殊的用处,需要用到的时候能够写出来即可。以上都是在介绍线程的一些常用API,其实还有一

13、个也应该知晓,那就是getId(),这个是用来活的线程的唯一标示的,比如有如下用法看打印输出结果得出的线程ID则可以作为判定此线程的唯一标示关于线程的常用API就介绍以上这几个,更多的可以等到需要用到的时候再针对的去查询,对于以上常用的则需要记住。4、线程的停止对于线程,它有这样的生命周期,就是新建、就绪、运行、阻塞和消亡对于这几种状态也比较好理解,首先是1. 新建状态:没有调用satrt方法就处于新建状态2. 就绪状态:即使此时已经调用了start的方法,线程也不会立马执行,必须等到jvm调用run方法线程才会真正的执行,而当前状态则为就绪状态3. 运行状态:就是调用了run方法之后4. 阻

14、塞状态:在运行状态如果调用了sleep方法就会处于阻塞状态5. 消亡状态:也就是线程被停止了关于线程的这几种状态,要好好说一说的就是线程的停止了,因为关于线程的停止不是想象中的那样,也许可以调用线程的stop方法将线程进行停止掉,但是,现如今,stop已经不推荐使用了,大多数停止一个线程将采用Thread.interrupt()这个方法。而关于interript也不是想象中的那样,只要调用了这个方法,线程就会停止,其实,调用了interrupt只相当于给当前线程打上了一个停止的标记,而此时,线程其实并没有真正的停止,而这其中很明显,缺少一些步骤。来看一段代码/* * 创建线程的我第一种方式 * 继承自Thread类 */

展开阅读全文
相关资源
相关搜索

当前位置:首页 > IT计算机/网络 > 其它相关文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号