Java中的多线程

来源:互联网 发布:淘宝钱包 编辑:程序博客网 时间:2024/06/05 04:09

  1.一个应用程序可以有多个进程,每个进程都有自己独立的内存空间,每次调用java命令,就会启动JVM进程,JVM进程的任务是执行Java代码;

  2.线程是进程的一个流程,进程由多个线程组成,也就是说,进程功能的实现是依靠线程执行Java代码实现的,每个线程执行不同的功能,一个进程中可以同时运行多个不同的线程,当一个进程中有多个线程运行的时候,称为线程并发。

  3.线程与进程的区别;

       进程有自己独立的内存空间,而同一个进程中所有的线程在同一个内存地址空间中工作,它们共享同一块内存和资源;

  4.JVM进程中,执行代码的功能由线程实现,(也就是说,应用程序的功能由进程实现,而进程的功能由组成进程的线程实现),每一个线程执行Java代码,有自己的程序计数器和方法调用栈。

     程序计数器:指向方法区要执行的下一条指令的字节码;

     方法调用栈:跟踪线程执行过程中调用的一系列方法调用,栈中的每一个元素称为栈帧,每当程序调用一个方法的时候,就会将代表该方法的栈帧压栈,栈帧用于存储方法的局部变量,参数和运算过程中的临时数据

      栈帧的组成:

         a.参数和局部变量

         b.操作数栈:存放临时数据

         c.栈数据区:用于定位堆区和方法区的特定数据(注意是数据,指令由程序计数器指定)

  5.JVM进程由多个线程组成,这些线程共同实现JVM进程的功能,当启动JVM进程时,JVM进程会启动一个主线程,这个主线程执行main方法,如果Java程序中没有创建自定义的线程,则所有的Java代码都由JVM的主线程执行。

  6.运行时数据区的方法区中保存线程执行的代码(再说一遍Java代码由线程执行),堆区保存线程执行需要的数据(以对象的形式存在),而栈区是线程的工作区,用于保存线程的工作状态;

  7.线程必须拥有CPU的使用权,才能够执行指令,计算机中机器指令的真正执行者是CPU

  8.执行main方法的主线程由JVM创建,在程序中用户可以创建自己的线程,这些线程可以和主线程并发执行,共同实现JVM的功能

      创建线程的方式有两种:

       a.继承Thread类

       b.实现Runnable接口

      8.1 继承java.lang.Thread类

            a.Thread的两个最重要的方法

               a.1 start()     用于启动线程,只调用线程的run()方法并没有启动线程,只是主线程在执行自定义线程的run()方法,而不是自定义线程在执行。

               a.2 run()       自定义线程的功能就是执行线程的run()方法  (这两点非常重要)

      8.2 一定要注意,主线程的任务是执行main()方法,用户子定义的线程的功能是执行run()方法,run()方法由用户自己定义

  9.new()一个线程,只是在运行时数据区的堆区创建该线程的对象,并没有启动,调用线程的start()方法时,启动该线程,线程处于Runnable状态,等JVM为它分配CPU,线程得到CPU的使用权时,会从run方法的第一条语句开始执行。

10.下述代码

    

   上述代码中共有三个线程执行Machine的run方法(分别是t1,t2和main),它们访问运行时数据区方法区中Machine类的指令,但是每个线程都有自己栈帧,记录调用方法的局部变量,参数和临时结果,可见,对于run方法中定义的局部变量,每个线程都有自己的版本,对于线程方法调用栈中的数据,每个线程都有自己的版本,每个线程的程序计数器都会指向方法区Machine类的指令字节码,而对于局部变量和临时结果,却是各有各的。

11.如果run()方法中使用线程类的实例变量,而且各个线程的操作对象都是同一个线程类的实例,则每个线程中都会有指针指向该线程类实例在堆区的位置,即对同一个实例变量进行操作,如果不同线程操作不同的对象,则它们分别保存指向不同对象在堆中的位置,操作相应对象的实例变量,从而对不同的变量进行操作

12.线程的状态:

     a.new一个线程是,只是在运行时数据区的堆区创建该线程的实例

     b.调用线程对象的start()方法时,启动该线程,JVM为线程分配方法调用栈和程序计数器

     c.阻塞状态 阻塞状态下的线程并没有执行完毕run()方法,在重新获得CPU之后,会继续执行

        c.1 位于对象等待池的阻塞状态

        c.2 位于对象锁池的阻塞状态

        c.3 其他阻塞状态,如执行sleep方法,调用其他线程的join()方法,或者发出I/O请求。

     d.死亡状态

        线程退出run()方法,可能是执行完run方法,或者遇到异常退出

13.

原创粉丝点击