美文网首页
Java - 多线程简介

Java - 多线程简介

作者: sunboximeng | 来源:发表于2018-05-17 15:50 被阅读8次

并行与并发

并行与并发.png

进程与线程的基本概念

什么是进程?

程序就是静态的文本,像乐谱一样。程序执行的时候,会从硬盘进入内存,内存中的程序就叫进程,就像正在演奏的乐谱。


乐谱.jpg

进程是计算机要执行的一个独立的计算任务,不同任务,时间花费不同。为了避免短任务长时间等待长任务的情况,计算机操作系统调度CPU在不同的任务之间进行轮转。

什么是线程?

一个进程也是由多个子任务组成的,这些子任务就称为线程,是程序执行的最小单位。比如对于一个监控系统来说,它不仅要把图像数据显示在画面上,还要与服务端进行通信获取图像数据,还要处理人们的交互操作。有了多线程就可以满足实时响应的需求。

进程与线程.jpg

进程是操作系统进行资源分配的基本单位,而线程是CPU调度的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。

既然多个线程是共同占有所属进程的资源和地址空间的,就会有冲突,协调办法在线程安全中讨论。

进程和线程的区别
  • 进程是操作系统分配资源的最小单位,线程是程序执行(也即CPU调度)的最小单位。
  • 一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线;
  • 进程之间相互独立。同一进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级的资源(如打开文件和信号),所以线程会有安全问题。
  • 调度和切换:线程上下文切换比进程上下文切换要快得多。
浏览器内核是多线程的程序

在内核控制下各线程相互配合以保持同步,一个浏览器通常由以下常驻线程组成:

  • GUI 渲染线程
  • JavaScript引擎线程
    JavaScript为处理页面中用户的交互,以及操作DOM树、CSS样式树来给用户呈现一份动态而丰富的交互体验和服务器逻辑的交互处理。如果JavaScript是多线程的方式来操作这些UI DOM,则可能出现UI操作的冲突; 如果Javascript是多线程的话,在多线程的交互下,处于UI中的DOM节点就可能成为一个临界资源,假设存在两个线程同时操作一个DOM,一个负责修改一个负责删除,那么这个时候就需要浏览器来裁决如何生效哪个线程的执行结果。当然我们可以通过锁来解决上面的问题。但为了避免因为引入了锁而带来更大的复杂性,Javascript在最初就选择了单线程执行。
  • 定时触发器线程
    浏览器定时计数器并不是由JavaScript引擎计数的, 因为JavaScript引擎是单线程的, 如果JavaScript引擎处于阻塞线程状态就会影响记计时的准确, 因此通过单独线程来计时并触发定时是更为合理的方案。
  • 事件触发线程
    当一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。这些事件可以是当前执行的代码块如定时任务、也可来自浏览器内核的其他线程如鼠标点击、AJAX异步请求等,但由于JS的单线程关系所有这些事件都得排队等待JS引擎处理。
  • 异步http请求线程

在Java中创建线程:

  • 继承 Thread 类
  • 实现 Runnable 接口,传入到 Thread 对象中。
  • 实现 Callable 接口
    好处:可以有返回值;可以抛出异常。
    弊端:代码比较复杂,所以一般不用

区别:

  • 由于Java只允许单继承,所以如果自定义类需要继承其他类,则只能选择实现Runnable接口。
  • 如果只是想共享任务,那就没有必要及继承一些用不到的属性和方法,实现接口即可。
  • 实现Runnable接口只能定义任务,不能直接使用Thread类中的方法。要想使用,需要首先获取当前线程对象。

使用匿名内部类创建线程

//新创建一个线程,重写run()方法。不重写方法并不会报编译错误,因为Thread类有run方法的实现。
new Thread() {
    @Override
    public void run() {
        super.run();
        // code
    }
}.start();

//新创建一个线程,将Runnable对象作为构造器参数传递
new Thread(new Runnable() {
    @Override
    public void run() {
        // code
    }
}).start();

线程的生命周期

女人的一生.png

枚举类 Thread.State 列出了线程的这6种状态:

  • new:创建
  • runnable:就绪,可运行的。但是不一定获得CPU时间片。
  • blocked:被动的。被同步块儿(锁)或 IO 阻塞。所以IO并不占用CPU。
  • waiting:主动的。调用了join、wait方法,不知道要等多久。wait是锁对象的方法。
  • timed waiting:主动的。调用了sleep方法,并指定了时间。sleep是线程的方法。
  • terminated:终止。run方法执行完毕或抛出异常
线程的一生.png

线程的上下文切换:存储和恢复CPU状态的过程,它使得线程执行能够从中断点恢复执行。栈是私有的,不会被覆盖。
虽然多线程可以使得任务执行的效率得到提升,但是由于在线程切换时同样会带来一定的开销代价,并且多个线程会导致系统资源占用的增加。

Thread类中的属性和方法

  • 属性:线程名字(get/setName、构造器传入)、优先级、是否为守护线程、所要执行的Runnable对象(由构造器传入)。
  • 方法
    • start():用来启动一个线程,在这个过程中,会为相应的线程分配需要的资源。

    • run():不需要用户来调用。当线程获得了CPU执行时间,便会自动调用。

      • run方法有点 像psvm,是要被线程运行的代码。
      • 通过start()方法去启动线程,而不是直接调用run()方法。run()方法中只是定义需要执行的任务,如果直接调用run()方法,会在当前线程中执行任务,并不会创建另外一个新的线程来执行任务。
      • 注意:run方法里面的变量是线程私有的,因为线程拥有独立的栈(抽奖)。但是实现Runnable接口的类中的成员变量是线程共有的(卖票)。
    • sleep():静态方法。让当前线程睡眠,让出CPU,但不会释放锁。也就是说如果当前线程持有对某个对象的锁,则即使调用sleep方法,其他线程也无法访问这个对象(相当于在厕所睡着了)。当线程睡眠时间满后,不一定会立即得到执行,因为此时可能CPU正在执行其他的任务。

      public static void main(String[] args) throws InterruptedException {
      
          System.out.println("1");
          Thread.sleep(2000);
          System.out.println("2");
      }
      
    • yield():该方法和sleep()方法有点相似,都可以让当前正在运行的线程暂停,区别在于yield()方法不会阻塞该线程,它只是将线程转换成就绪状态,让系统的调度器重新调度一次。

    • join():等待别的线程。比如在线程A中调用B.join(),其后的代码会在B线程执行完毕后才会继续执行。实际上调用join方法是调用了Object的wait()方法,这个可以通过查看源码可知。wait()方法会释放线程占有的锁。

    • interrupt():

    • currentThread():静态方法,用于获得当前线程,很像 this 的功能。

参考链接:Java并发编程:Thread类的使用

相关文章

  • Java多线程简介

    Java多线程简介 Java中内置了对多线程的支持,让多线程的开发方便很多,但同时也带来了另外的复杂,线程间的交互...

  • 后端架构师技术图谱(三)-并发、锁、设计模式(二)

    并发 多线程 《40个Java多线程问题总结》 线程安全 《Java并发编程——线程安全及解决机制简介》 一致性、...

  • Java - 多线程简介

    并行与并发 进程与线程的基本概念 什么是进程? 程序就是静态的文本,像乐谱一样。程序执行的时候,会从硬盘进入内存,...

  • Java多线程简介

    多线程在Java中无处不在,在上一篇(Java线程概念理解)中我们看到就算是一个最简单的Java类中也涉及到了多线...

  • Android开发 Java线程基础

    简介 本篇文章是带大家了解 Java多线程的基础知识.主要内容: 介绍多线程的概念, 了解多线程的优点, 状态, ...

  • redis分布式锁与多线程

    简介 关于多线程   首先,先复习一下Java多线程。我们都知道,启动一个Java程序,操作系统会为其创建一个进程...

  • 【Java 基础你一定要掌握的知识点】多线程

    Java 给多线程编程提供了内置的支持。在多线程编程之前,我们需要先了解什么是线程。 进程和多线程简介 进程:进程...

  • 一起学JDK源码 -- 开篇

    简介 对于java开发人员来说,你学过java基础,知道什么是对象、类、方法、变量,你了解过java IO、多线程...

  • JVM系列之:对象的锁状态和同步

    简介 锁和同步是java多线程编程中非常常见的使用场景。为了锁定多线程共享的对象,Java需要提供一定的机制来实现...

  • JVM系列之:对象的锁状态和同步

    简介 锁和同步是java多线程编程中非常常见的使用场景。为了锁定多线程共享的对象,Java需要提供一定的机制来实现...

网友评论

      本文标题:Java - 多线程简介

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