美文网首页
Java并发系列(一)

Java并发系列(一)

作者: f155b8f6e0ac | 来源:发表于2020-04-12 21:21 被阅读0次

    Java并发系列(一)

    什么是进程和线程

    本文主要讲线程,但是在开发过程中,经常将进程线程放在一起,那什么是进程?什么是线程?

    进程和线程

    进程:进程是操作系统结构的基础,是一次程序的执行(是不是非常抽象?!)。其实简单来说,我们打开任务管理器,呈现给我们的那个列表里面的所有.exe呈程序就可以理解为进程
    线程:线程可以理解为在进程中独立运行的子任务;例如:微信在运行的过程中,有很多子任务同时进行,如视频通话,下载文件,传输数据等。这些不同的任务都可以同时运行,那么这每一项子任务都可以理解为线程

    进程和线程的关系

    进程负责向操作系统申请资源;在一个进程中,多个线程可以共享进程中相同的内存和文件资源。所以多线程之间的通信比进程之间的通信更有效、更容易。

    下面我们将详细介绍线程的相关知识。

    Java中如何创建一个线程

    创建一个线程会使用到Java中的Thread类。大致分为如下步骤:
    1.将执行这个任务的代码放在一个类的run方法中,值得注意的是:这个类必须要实现Runnable接口,这个接口非常简单,只有一个run方法。

    Runnable r = () -> {// task code};
    

    2.从这个Runnable构造一个Thread对象
    Thread t = new Thread(r);
    3.启动线程
    t.start();

    下面用个简单的例子说明上述的步骤以及理解多线程

    Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("Thread1: " + 10 * Math.random());
                }
            });
            Thread t2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("Thread2: " + 10 * Math.random());
                }
            });
            t1.start();
            t2.start();
    

    在上述代码中,创建了两个线程,这两个线程都会打印一个0-10以内的随机数,运行上述的代码,我们会发现,输出的结果是不确定的,这恰恰说明了,在这个程序(进程)中,同时运行了两个进程,结果我们不能确定。

    注:不要调用Thread类和Runnable对象的run方法,直接调用run方法只会在同一个线程中执行这个任务——而没有启动新的线程。实际上,在调用start()方法这会创建一个执行run方法的新的线程

    线程的状态

    线程的状态分为6种,分别是

    • New——新建
    • Runnable ——可运行
    • Blocked——阻塞
    • Waiting——等待
    • Timed waiting——计时等待
    • Terminated——终止

    新建的线程

    当使用new操作符创建一个新线程,这个时候线程的状态是:新建的,还没有开始运行

    可运行的线程

    一旦线程调用了start()方法,就说明线程进入了可运行状态
    但是值得注意的是,一个线程处于可运行状态,并不代表他正在运行,也有可能没有运行(是不是觉得很神奇 :smile:.),

    其实,运行中的线程有时候需要暂停,让其他线程有机会运行。这个机制跟线程调度有关,例如,抢占式调度系统,会给每个可运行的线程一个时间片来执行任务,当时间片用完,操作系统会剥夺该线程的运行权,并给另外一个线程运行的机会。所以可运行的线程可能正在运行也可能没有运行

    注:使当前正在执行的线程交出运行权给另外一个线程,使用static void yield(),这个镜头方法

    阻塞和等待的线程

    当线程处于阻塞或等待状态时,**它暂时是不活动的。它不运行任何代码,而且消耗最少的资源,需要由线程调度器重新激活这个线程。具体的细节取决它是如何到达非活动状态的

    • 当一个线程试图获取一个内部的对象锁,但是恰好这个锁被其他线程占有,该线程就会被阻塞,只有当其他线程释放了这个锁,并且线程调度器允许该线程持有这个锁,它将变成非阻塞状态。
    • 当一个线程需要等待另一个线程通知调度器出现某个条件的时后,这个线程变会进入等待状态,等待主要调用了Object.wait()方法或者等待java.util.concurrent库中的Lock或Condition时,会出现此情况。
    • 使得进程变成等待状态的函数,有几个方法有超时参数,调用这些方法会让线程进入计时等待。这一状态将一直保持到超时期满或者接收到适当的通知。

    简之,线程各个状态的关系可以用下图表示:

    线程状态图.png

    终止的线程

    线程会由下面两种情况终止:

    • run方法正常退出,线程自然终止
    • 因为一个没有捕获的异常终止了run方法,使得线程异常终止。

    后面讲继续介绍多线程开发的相关知识(同步,锁等),敬请期待~

    相关文章

      网友评论

          本文标题:Java并发系列(一)

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