Java学习之初识线程

作者: 戒律和尚 | 来源:发表于2019-04-29 20:25 被阅读4次

“身之主宰便是心,心之所发便是意,意之本体便是知,意之所在便是物 --摘自阳明先生语录”

微信图片_20190423212724.jpg

1、概念
在说线程之前我们先了解关于进程的一些知识,什么是进程?
程序一旦运行就是一个独立的进程,以windows为例,打开windows任务管理器,在应用程序栏中就是一个个的进程,进程可以看做是程序执行的一个实例。

每个进程都有独立的代码和数据空间,进程间的切换会有较大的开销,一个进程包含1至n个线程。如下图我开启了两个Chrome程序的进程。


1556325559736.png

再说说什么是线程?
线程是一个比进程粒度更小的执行单位,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。每个程序里至少有一个线程(主线程,也叫入口线程,只能有一个)。

2、线程的使用方法
在Java中线程的实现方式有三种 实现Runnable接口、继承Thread类、实现Callable接口,后两者都跟Runnable有关,本文只讲解前两种,后面会有单独的文章来说Callable。
实现Runnable接口方式如下:

public class Test implements Runnable{
    @Override
    public void run() {
        System.out.println("线程启动,开始执行......");
    }
    
    public static void main(String[] args) {
        Test test = new Test();
        Thread thread = new Thread(test);
        thread.start();
    }
}

运行上面的代码将打印:线程启动,开始执行......

Runnable接口只有一个run方法,该方法是在线程启动后执行的方法,使用Runnable的方式无法直接使线程处于就绪状态,你必须通过创建Thread实例来创建新的线程。
继承Thread类方式如下:

public class Test extends Thread{
    @Override
    public void run() {
        System.out.println("线程启动,开始执行......");
    }
    
    public static void main(String[] args) {
        Test test = new Test();
        test.start();
    }
}

Thread类其实也实现了Runable接口,如果用Thread,重写run方法后就可以直接启动线程了。
调用Thread类的start方法后,线程不会立马执行,这只是使该线程处于就绪状态,处于就绪状态的线程会等待计算机分配CPU执行,也就是说具体线程什么时候执行得由计算机来决定。
PS:不能直接调用run方法,如果调用run方法那么只会当作一次普通的方法调用而已。
不能重复调用start方法:

public class Test extends Thread{
    @Override
    public void run() {
        System.out.println("线程启动,开始执行......");
    }
    public static void main(String[] args) {
        Test test = new Test();
        test.start();
        test.start();
    }
}

这段代码里连续调用了两次start方法,在执行到第二次start方法调用时将报java.lang.IllegalThreadStateException异常,该异常表示一个Thread不能重复调用start方法 。
3、生命周期
一个线程的生命周期分为五种,它要经过新建、就绪、运行、阻塞和死亡5种状态。
新建:使用new关键字创建了一个线程之后,该线程就处于新建状态。
就绪:调用了start()方法之后,该线程处于就绪状态。
运行:只有就绪状态下的线程才能获得计算机分配的CPU,开始执行run()方法,则该线程处于运行状态。
阻塞:阻塞状态是线程因为某种原因放弃CPU使用权,失去所占用资源之后,暂时停止运行。
死亡:当线程执行完run方法或者发生异常退出,线程结束生命周期。PS:调用该线程stop()方法来结束该线程——该方法容易导致死锁,不推荐使用,JDK已废弃

阻塞状态分为三种情况:
等待阻塞:调用wait方法暂停执行,并且放弃已经获得的锁,进入等待状态。
同步阻塞:获取对象的同步锁时,如果同步锁被其他的线程占用,则JVM会把该线程放入锁池中。
其他阻塞:如执行了sleep(睡眠)方法,或等待I/O设备等资源,将让出CPU并暂时停止自己的运行,进入 阻塞状态。
注意:进入阻塞状态的线程,当接触阻塞状态后将重新进入到就绪状态,而不是马上运行。

4、常用方法
start() :调用该方法使线程进入就绪状态
run():获得CPU执行的线程将运行该方法
sleep():这是一个静态方法,通过Thread.sleep()调用,调用该方法放弃CPU资源,使线程休眠一段时间,该方法的参数为毫秒
join():等待该线程终止,也就是说该线程是指的主线程等待子线程的终止,在子线程调用了join()方法后面的代码,只有等到子线程结束了才能执行
yield():暂停当前正在执行的线程对象,并执行其他线程
wait:调用该方法后线程将进入等待状态,只有等待另外线程的通知或被中断才会返回,需要注意的是调用wait()方法后,会释放对象的锁
notify():通知一个线程继续运行
notifyAll:通知所有线程继续运行

5、总结
1、使用Runnable接口可以避免Java中单继承的限制(推荐实现Runnable接口)
2、使用Runnable接口需要另外创建Thread实例来创建新的线程
3、不能直接调用run方法,否则将作为一次普通的方法调用
4、不能连续调用start方法

如果你觉得不错就分享出去
你也可以关注公众号,随时获取最新文章
PS:近期将在公众号做一波活动,可关注公众号回复暗号:“Java” 查看礼品~~


1555737540494.jpg

相关文章

  • Java学习之初识线程

    “身之主宰便是心,心之所发便是意,意之本体便是知,意之所在便是物 --摘自阳明先生语录” 1、概念在说线程之前我们...

  • JAVA线程面试题书目录

    JAVA线程面试题之1) 什么是线程? JAVA线程面试题之2) 线程和进程有什么区别? JAVA线程面试题之3)...

  • 【Java并发学习】之线程的同步

    【Java并发学习】之线程的同步 前言 在前面一个小节中,我们学习了线程的概念以及在Java中创建任务的方式,并且...

  • Java多线程编程核心技术(1)

    第一章 java多线程技能 目标: 0、初识线程 1、线程的启动 2、使线程暂停 3、停止线程 4、线程优先级 5...

  • ThreadPoolExecutor

    参考文章:Java并发学习之线程池ThreadPoolExecutor的小结并发番@ThreadPoolExecu...

  • 深入浅出线程Thread类的start()方法和run()方法

    一、初识 java的线程是通过java.lang.Thread类来实现的。VM启动时会有一个由主方法所定义的线程。...

  • java中的线程池初步了解

    java学习之线程池 为什么要使用线程池?:在java中创建和销毁线程是非常损耗系统性能的,在开发过程中尽可能的少...

  • 初识 Java 线程池

    本文引领大家进入线程池的世界 很多人对线程的认识可能比较熟悉, 知道它能开启一个任务去做某些事情, 那么线程池又是...

  • 初识Java多线程

    第一章 Java多线程技能 1)线程的启动;2)如何使线程暂停;3)线程的优先级;4)线程安全相关的问题 1.1 ...

  • 【并发编程系列3】volatile内存屏障及实现原理分析(JMM

    初识volatile Java语言规范第3版中对volatile的定义如下:Java编程语言允许线程访问共享变量,...

网友评论

    本文标题:Java学习之初识线程

    本文链接:https://www.haomeiwen.com/subject/gkwunqtx.html