java多线程中篇(一) —— Thread详情

简介

  简言之,现在的JDK线程模型基于操作系统原生线程,所以模型依赖于操作系统对线程的支持,另外Windows和Linux系统提供的线程模型就是一对一的
  所以可以简单认为:
    现在Java线程与操作系统线程一对一映射
    现在的Java线程,就是操作系统中的线程
 
一些都是Thread Thread是Java对线程的抽象描述,所以多线程编程模型必然是针对Thread。不管JVM与操作系统的线程到底如何映射,到底如何运行,面对Java,程序员看到的就只是Thread。

多线程开发就是操纵Thread对象

  Thread的抽象模型往简单了说就是Thread这个类,他有属性字段,有public方法,也有封装到线程任务(Runnable),对于一个Thread的设置,他就那些可配置项目,不多不少
   所以只要你理解了Thread的的抽象模型,那么你就能够很清晰的对你需要的Thread进行配置。
   而多线程编程模型中的解决思路就如同下棋时的套路那般,可以让你更好更快更全面的写出来多线程应用程序。
创建Thread 对象,使用Thread对象,看起来似乎是超乎寻常的简单,然后并不是。对于线程的操作有多种方法,既然是多线程就不止一个线程,那么多线程、多交互方法,必然产生很多种复杂的协作逻辑,如何能够正确高效的组织,也是非常考验智商的。 

Java线程逻辑:线程的核心为线程控制线程同步线程通信

  • 对于Thread类本身,拥有其自身的属性,比如名字、Id、优先级、状态等,这就是进程的控制信息;
  • 对于Thread中封装的任务,Java提供了synchronized,volatile关键字用于控制共享资源的访问,这就是进程的同步;
  • 对于Thread中的一些行为(以及从Object继承而来的),比如join、wait则相当于进程的通信。

    

Java多线程编程到底是什么呢?

  所以说了这么多,到底Java多线程编程到底是什么?我们前面说只有两个步骤“ 创建Thread 对象,使用Thread对象
  这两个部分是对线程本身的控制与处理,但是在使用Thread对象时,还有一个最重要的部分,也就是为什么我们要使用线程?
  还不是为了执行任务?
    所以说,任务的执行也是非常重要的代码,因为,多线程中的代码不再是简简单单的完成任务那么简单,因为如果涉及到共享资源的访问,所以就是涉及到进程同步的问题。
  学习java多线程,如果理解一下几部分会好很多。
第一个部分,理解清楚Java对线程概念的抽象以及Thread支持的控制操作方法---也就是Thread类本身。
第二个部分,理解清楚Java中同步的逻辑,也就是同步关键字的透彻理解。
第三个部分,理解清楚Java对于线程通信的抽象,也就是相关方法比如wait 的逻辑

 Thread类

1. Thread概述

    

 一个Thread包括了三方面的信息:基本信息、线程自身的行为、线程任务

    

 1.1 基本信息

基本信息包括下面这些
  • 名称、id、优先级、状态、线程组、守护线程状态、堆栈信息跟踪
  • 上下文类加载器设置、异常处理器设置 
  • 是否存活、当前线程是否有权修改该线程

    

名称:线程是有名字的,属性name,如果不指定名称,那么会生成thread-0,thread-1.........thread-N 这种名称

ID:类比人的话,ID就是身份证号,线程的唯一标识符。线程ID是一个正的long数,在创建该线程时生成,线程终止时,ID可被重新使用

优先级:线程默认的优先级是NORM_PRIORITY=5,一般情况下不需要设置优先级因为你设置了优先级并不一定总是完全按照你的想法进行,前面说过,Java线程是操作系统原生线程的映射,要依赖操作系统。

   如果设置的值不在有效范围内,直接抛出异常。万万不要业务逻辑依赖你自以为的线程优先级

状态:新建、就绪、运行、阻塞、结束

线程组:线程组用于对线程进行管理,ThreadGroup 线程组表示一个线程的集合。此外,线程组也可以包含其他线程组,线程组构成一棵树,在树中,除了初始线程组外,每个线程组都有一个父线程组  

守护线程状态:可以将一个Thread标记为守护线程。守护线程,可以认为是后台线程。需要注意的是,必须是线程启动前设置,不然你试试看,分分钟  throw new IllegalThreadStateException()。

堆栈信息跟踪:待更......

上下文类加载器设置:待更新......

异常处理器设置:待更新......

是否存活:线程从启动之后,直到最终终止,这一个过程被称之为是活动状态换句话说,一个线程start之后,除非他被终止,否则任何时刻都是true。isAlive就是用于检测线程是否处于活动状态。

当前线程是否有权修改该线程:判定当前运行的线程是否有权修改该线程。比如线程Thread aThread,在main方法中调用aThread.checkAccess,此时当前线程是主线程main,

              目标是aThread 那么就是检测主线程是否有权利修改线程aThread。


 1.2 线程行为

  Thread中的方法,有一些是线程本身的行为控制或者通信,另外还有一些相当于是工具类。

    

currentThread: 返回对当前正在执行的线程对象的引用,线程是Thread,哪个Thread正在运行,那么就返回哪个对象就好了,返回类型就是Thread。

activeCount:返回的是当前线程,所在的线程组中,活动线程的个数

enumerate:线程的抽象是Thread,每一个线程都是一个Thread,既然是对象那么就有类似寻常对象的操作,比如保存到数组。enumerate就是用来讲当前线程的、所属线程组中的、以及子组中的每一个活动线程复制到指定的数组中,返回值为复制的线程的个数

是否持有指定监视器的锁:如同前面提到过的互斥量,Java中同步时需要用到一个对象锁,如果一个线程请求的锁被别的线程获得,那么就需要进行等待,持有了锁就可以进入临界区。

            方法用于判断当前线程,当前线程、当前线程。针对于某个对象,是否持有对应的锁,当且仅当当前线程在指定的对象上保持监视器锁时,才返回 true。


 1.3 线程任务 

  线程的任务核心是Runnable,内部持有一个Runnable target,构造时如果不进行设置那么为null。

调用start方法启动后,会调用run方法,如果不重写run方法,或者构造时不进程传递,那么target为null
很显然如果target,run方法就相当于一个空方法,也就是什么都不做。

 

 简言之,Java对于线程以及线程任务,进行了抽象分离,对线程的抽象为Thread,而对于线程任务的抽象就是Runnable


总结

  Thread中的方法主要用于对线程进行控制也可以用作通信,还有一些是基于类设计层面的,添加进来的一些工具类,可以对线程的一些信息进行控制、获取 线程任务是通过Runnable进行抽象,简言之,
  Thread表示线程,Runnable表示任务。
  “分别是为了更好地重逢”放到这里非常合适,解耦是为了更好地协作
  线程本身线程需要执行的任务进行分离,无论是从抽象概念上还是认知理解上,亦或者是二者独立的发展上,解耦都有多种好处。
    

 在Java这一面向对象的语言中,多线程编程就是“多Thread对象编程”

感谢:https://www.cnblogs.com/noteless/p/10354699.html

猜你喜欢

转载自www.cnblogs.com/FondWang/p/11982795.html