.Net转Java自学之路—基础巩固篇十二(多线程)

多线程:

  JVM的启动是一个多线程程序;其中有一个程序负责从主函数开始,并控制程序的运行流程;同事为了提高效率,还启动了另一个控制单元,专门负责堆内存垃圾的回收。

  负责执行征程程序代码的线程,称为主线程。

  该线程执行的代码都存放于主函数中。

  负责垃圾回收的线程,该线程代码在finalize中。

  进程:当前正在执行的程序;代表一个应用程序在内存中的执行区域。

  线程:是进程中的一个执行控制单元,执行路径。

    一个进程中至少有一个线程在负责控制程序的执行。

    一个进程中如果只有一个执行路径,那么这个程序称为单线程。

    一个进程中有多个执行路径时,这个程序称为多线程。

  特点:提高效率

  定义:线程的定义用 Thread 类。

  创建方式:

    1、创建一个 Thread 子类,并覆盖 Thread 中的 run() 方法。

    覆盖 run() 方法是为了让该线程执行自定义的代码段;这时 new 一个该子类的对象,其实就是在创建一个线程。

    2、创建 Thread 对象。

    3、实现 Runnable 接口。

  在内存中的表现形式:

    1、堆内存中产生一个对象。

    2、需要调用底层资源,去创建执行路径。

  如果直接调用该对象的 run() 方法,这时,底层资源并没有完成线程的创建和执行,仅仅是简单的对象调用方法的过程,这时,执行控制流程的只有主线程。

  开启线程:

    调用 Thread 类中的 start() 方法。

    作用:1、开启线程。2、调用线程的 run() 方法。

  特性:

    随机性。

  为了对各线程的标识,有一个默认的名称,用 getName() 获取,名称编号从0开始;例:Thread-0、Thread-1......

  重新定义线程名称:

    1、线程对象.setName(strName)。

    2、Thread(strName) 构造函数定义线程名称。

  通过 currentThread() 返回当前线程对象,该方法为静态。

  线程:

    1、start()      开始

    2、run()        运行

    3、sleep(time)   睡眠

    4、wait()/wait(time) 等待

    5、notify()     唤醒

    6、临时阻塞特点:该线程具备执行资格,但不具备执行权。

线程安全问题:

  因为线程的随机性,有可能会导致多线程在操作系统时发生数据错误的情况产生。

  产生原因:

    当线程中的多条代码在操作同一个共享数据时,一个线程将部分代码执行完毕,还没有继续其他代码时,被另一个线程获取CPU执行权,这时,共享数据操作就有可能出现数据错误。

    简单来说,多条操作共享数据的代码被多个线程分开执行造成的。

  涉及的内容:

    1、共享数据。2、是否被多条语句操作。

    这也是判断多线程程序是否存在安全隐患的依据。

  解决方式:

    Java 的同步机制。

    解决原理:

      让多条操作共享数据的代码在某一时间段,被一个线程执行完,在执行过程中其他线程不能进行该代码段的操作。

    同步格式:

      synchronized(对象) { 同步代码段 }

    优点:解决了多线程的安全问题。

    弊端:效率降低。

    前提:

      1、必须是俩个/俩个以上的线程在执行同一个同步代码段。

      2、必须保证多个线程使用的同一锁。

    已加上同步,但安全问题依然存在,按照以上俩个前提排查。

    如同步代码段提取成一个函数,那么需要该函数用 synchronized 修饰下即可。

  同步代码段和同步函数的区别:

    代码段使用的锁可以是人员对象,而同步函数的锁是固定对象 this。So、一般建议用同步代码段,当然,如果对象可以使用 this,那么可以简化同步函数的形式。

原文地址:https://www.cnblogs.com/zltao/p/9942875.html