线程操作类

线程操作类:

线程操作类是Thread类,可以使用这个类进行线程方面的相关操作,例如获得当前线程对象,令当前睡眠,强制激活线程等等,可以直接调用静态的方法。

如何获得当前线程:

currentThread();是获得当前线程对象的方法,可以直接使用也可以将得到的对象存放到变量中,得到对象后还可以使用getName();方法得到线程对象的名称,还有getId();方法可以得到线程对象的编号,getPriority();方法则可以可以得到线程对象的优先级。

代码示例:

运行结果:

如何使线程在某个地方就结束呢:

stop();方法,从名字也看的出来,这方法就是调用后会终止线程的,这个方法会直接把线程对象销毁,来起到结束线程。一旦线程结束了,接下来的代码就不会被执行,不管是什么代码,还有需要注意的一点是:线程只有一次生命,结束之后等于死亡状态,这个“死掉”的线程是不可以再复活的,所以没有办法再继续启动的。

代码示例:

运行结果:

从结果可以看出,线程结束后的两句打印函数没有被执行

认识一下线程的状态:

State是枚举类型,使用这个类可以得到所有状态,要注意的是并不是得到某个线程对象的状态,想要得到某个线程的状态要使用那个线程对象调用getState();方法获得。

   Thread.State.NEW  新建状态

当线程对象刚刚被创建,还没有进入运行、开启的时候就是新建状态。

Thread.State.RUNNABLE 运行状态

当线程对象进入运行、开启的时候就是运行状态。

Thread.State.WAITING  无时间限制等待状态

当线程对象调用wait方法时,并且没有设置时间参数时就会进入此状态。

Thread.State.TIMED_WAITING  有时间限制的等待状态

当线程对象调用sleep方法时,并且设置时间参数后就会进入此状态。

Thread.State.TERMINATED   线程死亡状态

线程对象被销毁,线程结束时就会进入死亡状态。

Thread.State.BLOCKED  线程死锁状态

在线程同步里,两个线程陷入互相等待对方的时候就会进入线程死锁状态。

如何开启一个线程:

想要开启一个线程,首先要写一个类继承于Thread类,并且要重写run();方法,然后创建线程对象后使用对象调用start();方法来启动线程。

为什么一定要重写run();方法呢,因为线程对象在调用start方法的时候会向系统申请资源,接着线程就会进入到运行状态,线程进入到运行状态的时候会调用run方法,run方法结束后线程就会进入死亡状态。线程进入运行状态时首先调用的是run方法,做个不是很恰当的比喻就是:run方法就类似于普通类的main方法一样,运行时实际上只会执行这个方法里面的代码。所以你想要线程执行你编写的代码就必须重写run方法。

当你想给线程起一个你想出来的名字可以使用线程对象调用setName方法来设置线程的名字。

代码示例:

运行结果:

从代码的运行结果来看,有人可能会疑惑为什么main方法里的打印函数明明在最后一句,为什么会先执行?

实际上呢,问题不在于谁先执行了,首先main也是一个线程,你开启的也是一个线程,线程之间是独立并行的,至于谁的代码先执行完是要看谁跑的快,就像食堂开饭一样,先到的先打到饭后到的后打到饭,所以也是会出现main线程后面才执行完的情况的。

线程这货可不止继承Thread类这一种创建方式,线程还可以实现Runnable这个接口来创建。至于为什么还有这种创建方式,因为别忘了java只能单一继承,万一继承了其他的类又要把这个类作为线程的时候就只能使用接口的方式了,而且接口也能多实现多个。

  代码示例:

运行结果:

可能看到代码后,又有人会疑惑,为什么构建Thread类的时候需要将当前的类的实例对象传递给Thread的构造器?

因为在Thread的内核代码里的原理是这样的:

也就是说,你将对象传递过去后,这个类会将这个对象经过一系列的处理后保存到这个Thread类的属性里,所以当你在你写的类中使用Thread的对象调用run方法的时候就又会调回到你原来的类上面去,简单的理解就是调用run的时候在里面浪了一圈之后就回到你写的run方法上去了。

sleep方法:

sleep方法可以设置一个时间使线程进入睡眠状态,线程进入睡眠状态后会根据你设置的时间参数醒来。使用sleep时要知道的一点是:sleep方法是静态的,在当前的线程下不能使用这个方法来让另一个线程进入睡眠状态。

例如:A线程不能在自己的线程里使用B线程的对象来调用sleep方法,因为即便是使用B线程的对象来调用了也是A线程会进入睡眠状态并不是B线程。所以由此可知在哪个线程里遇到sleep方法哪个线程就会进入睡眠状态,即便你使用的是其他线程对象调用的也是如此。

还有一点就是:调用sleep方法线程进入睡眠状态后,如果这个线程被强制激活、叫醒了,就会抛出异常。因为你想想睡着睡着被叫醒,是个人都有起床气嘛,呸,说错了不是人是线程,但是睡到自然醒就不会有这个问题。

当线程对象进入睡眠状态,你想要在代码运行到某处的时候叫醒睡眠中的线程的话,可以使用睡眠中的线程对象调用interrupt();方法,此方法可以强制激活睡眠中的线程,但是这种激活方式就如同上面所说的会抛出异常,需要注意处理异常;

激活线程代码示例:

运行结果:

不激活线程代码示例:

运行结果:

主线程和子线程:

主线程是开启某个线程的线程,被这个线程开启的线程就是子线程。这个说法说起来有点绕口,换个比喻就是:例如main是一个线程,在main里开启了一个A线程,那么main就是主线程A就是子线程。

主线程会等待子线程结束才结束,也就是说子线程还有一秒没干完活,主线程就不会自己偷跑。

但是有个方法可以让主线程结束的时候就把子线程结束掉,称之为守护型线程,只要主线程结束,不管子线程是否还有代码没有执行完都强制随着主线程结束,这个方法就是setDaemon(boolean on); 使用线程对象调用此方法时给参数传递个true就代表这是个守护型线程,要注意的是这个方法一定要在start方法之前调用,在start方法之后调用是会抛异常的,因为你得在线程启动前声明这是个守护型线程。

  代码示例:

运行结果:

因为主线程先结束了,子线里的循环还没来得及进行,所以count的值为0。

join方法:

此方法的作用是等待线程结束,一般在书面上写的意思是合并线程方法,从其作用来理解成等待线程结束会好理解一些,只有等待到线程结束了,才会执行下面的代码。

这个方法可以传递一个时间参数,用来表示如果线程到指定的时间还没结束就不等了,就会继续执行下面的代码。如果不设置时间参数的话,就会一直死等到线程结束为止,才会往下执行。

  不设置时间参数的代码示例:

运行结果:

设置时间参数的代码示例:

运行结果:

使用线程优化之前的代码统计器的统计代码的速度:

线程类:

文件搜索类:

每找到一个文件就开启一个线程去统计

运行结果:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java多线程与并发笔记

    synchronized主要是用于解决线程安全问题的,而线程安全问题的主要诱因有如下两点:

    端碗吹水
  • Java并发编程(5)- J.U.C之AQS及其相关组件详解

    Java并发包(JUC)中提供了很多并发工具,这其中,很多我们耳熟能详的并发工具,譬如ReentrangLock、Semaphore,而它们的实现都用到了一个共...

    端碗吹水
  • Java并发编程(7)- 线程调度 - 线程池

    平时有接触过多线程开发的小伙伴们应该都或多或少都有了解、使用过线程池,而《阿里巴巴 Java 手册》里也有一条规范:

    端碗吹水
  • Java多线程学习(二)——Thread类的方法使用

    停止线程意味着在线程处理完任务之前停掉正在做的操作,也就是放弃当前操作。有以下三种方法终止正在运行中的线程:

    小森啦啦啦
  • 从使用到原理学习Java线程池

    在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销...

    哲洛不闹
  • 美团面试题:Java-线程池 ThreadPool 专题详解

    java.util.concurrent.Executors提供了一个 java.util.concurrent.Executor接口的实现用于创建线程池

    前端博客 : alili.tech
  • Java 多线程编程(“锁”事碎碎念)

    对于多个线程间的共享数据,悲观锁认为自己在使用数据的时候很有可能会有其它线程也刚好前来修改数据,因为在使用数据前都会加上锁,确保在使用过程中数据不会被其它线程修...

    叶志陈
  • Java 多线程编程(聊聊线程池)

    线程是一种昂贵的系统资源,其“昂贵”不仅在于创建线程所需要的资源开销,还在于使用过程中带来的资源消耗。一个系统能够支持同时运行的线程总数受限于该系统所拥有的处理...

    叶志陈
  • 编程体系结构(05):Java多线程并发

    线程是操作系统能够进行运算调度的最小单位,包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程...

    知了一笑
  • 新手一看就懂的线程池

    线程池是帮助我们管理线程的工具,它维护了多个线程,可以降低资源的消耗,提高系统的性能。

    好好学java

扫码关注云+社区

领取腾讯云代金券