博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线程讲解(一)
阅读量:3958 次
发布时间:2019-05-24

本文共 2195 字,大约阅读时间需要 7 分钟。

线程说明

跟进程比较,线程的特点:

  • 线程本身不能单独运行,它必须在一个程序中运行.
  • 线程是程序的内部控制流,一个进程在执行过程中,为了同时完成多个操作,可以创建多个线程,形成多条执行线索.每个线程有自己的堆栈、自己的程序设计器和自己的局部变量.
  • 每个进程都有一段专用的内存区域.而同一个进程的各线程间可以共享相同的内存空间(代码空间和数据空间),并且利这些共享内存来实现数据交换、实施通信以及必要的同步工作.

线程是程序中的一个执行流,一个执行流是由CPU运行程序代码并操作程序的数据形成的.JAVA 中的线程模型就是一个CPU、程序代码和数据的封装体.线程在JAVA 中是由 java.lang.Thread 类来定义和描述的,程序中的线程都是 Thread 的实例.

线程的创建

JAVA 提供了一下两创建线程的方法:

  • 继承类 Thread.定义一个类,作为类 Thread 的子类,在该类上重写方法run().
  • 实现 Runnable 接口.定义一个类,实现接口 Runnable,在该类上重写方法run().

继承 Thread 类

方法run()是线程在运行时所要执行的动作,但是在执行线程过程中,并不是直接调用该方法,而是在由该类创建实例对象后,通过方法start()来启动线程.

实现 Runnable 接口

接口 Runnable 只有一个抽象方法run(),在实现该接口的类中需要重写该方法.

在线程运行时,实现了接口 Runnable 的对象需要由类 Thread 封装为线程实例,类 Thread 的构造方法可以接受接口 Runnable 的实例,然后线程实例通过start()方法启动线程.

两种方法比较

两种创建线程的方法有所区别,各有利弊.

  • 使用继承类 Thread 的方法相对简单,比较直观,但是由于 JAVA 语言是单继承机制,使得一个类继承了类 Thread 之后不能再继承其他类.
  • 通过实现 Runnable 接口的方法来创建线程时,虽然在生成线程实例时需要再通过 Thread 实例对 Runnable 实例进行封装;但定义时该类可以再继承其他类.
    Thread 类不支持线程重用.在处理多任务时,通常会创建多个线程,让一个线程执行一个任务.其实也可以创建几个线程,然后重用这些线程执行任务,相关可以学习线程池.

线程的属性

线程本身有一些特有的属性,例如:线程标识符、线程名以及线程间的优先级属性等.通过这些属性,可以用来识别一个线程、了解线程的状态、控制线程的优先权等.

线程标识符

该属性为每一个线程存储了唯一的一个标识符,通过线程标识符,可以对线程进行区分.使用方法getId().

thread: this.getId()
Runnable: Thread.currentThread().getId()

线程名

每个线程默认有一个名字,默认的名字采用 Thread-1,Thread-2…形式;也可以对创建的线程设置线程名.通过getName()可以获取线程名.

线程的状态

一个线程从创建、运行到终止称为一个生命周期.线程在其生命周期中要经历创建、就绪、运行、阻塞和终止5中状态.通过getState()获取运行状态.

创建 New

当一个 Thread 类或其子类使用 new 关键词声明一个对象实例时,此时线程处于创建的状态.处于创建状态的线程有自己的内存空间,但是线程还没有运行.

就绪 Runnable

处于创建状态的线程通过调用start()方法启动后,线程进入就绪状态.这时的线程就已经拥有了运行所需的所有条件,将进入线程队列等待CPU调度.由于还没有获取到CPU的时间片,所以不会立即执行.

运行 Running

当处于就绪状态的线程被调度,并获得CPU资源时,便进入运行状态.

  • 运行状态的线程执行Run()方法中的操作.
  • 运行状态线程不是一直占用CPU的,而是根据CPU的调度策略有关.CPU时间片用完后,就会转为就绪状态.
  • 操作系统的调度策略,会考虑线程的优先级.高优先级的线程获得CPU调度几率要大.
  • 多于处理器内核数目的线程数,并不能提供执行效率.

阻塞 Blocked

在某些情况下,一个正在运行的线程会让出正在使用的CPU资源,进入阻塞状态.

  • 某些共享资源(打印机或文件资源)被占用.
  • 等待I/O操作.
  • 调用了wait、sleep或者 suspend 等方法.
  • 尝试获得锁,而该锁正在被其他线程使用.

为了提供CPU的利,当一个线程被阻塞时,另一个线程就获得了运行的机会.

终止 Terminated

线程到达终止状态可能有几种原因:

  • 线程的方法run()执行结束.
  • 线程通过某些方法(如Destory()) 被提前终止.
  • run()方法执行中发生了未捕获的异常.

线程的优先级

在 JAVA 语言中,每个线程都有一个优先级,不同线程可以被赋予不同的优先级.

通过getPriority()方法获取线程优先级,通过setPriority()方法设置线程优先级.
线程优先级共分为10个级别,最低为1,最高为10,默认优先级为5.

守护线程

前面提到的都是用户线程,另外还有一个是守护线程.两者没有什么太大不同,守护线程的唯一作用是为用户线程提供服务.

通过 setDaemon() 方法,将线程设置为守护线程.

转载地址:http://cyazi.baihongyu.com/

你可能感兴趣的文章
P5-c++内存模型和名称空间-01头文件相关
查看>>
P6-c++内存模型和名称空间-02存储连续性、作用域和链接性
查看>>
P9-c++对象和类-02构造函数和析构函数总结
查看>>
P10-c++对象和类-03this指针详细介绍,详细的例子演示
查看>>
bat备份数据库
查看>>
linux数据库导出结果集且比对 && grep -v ---无法过滤的问题
查看>>
shell函数与自带变量
查看>>
linux下shell获取不到PID
查看>>
sort详解
查看>>
linux,shell中if else if的写法,if elif
查看>>
shell中单引号、双引号、反引号的区别
查看>>
shell脚本死循环方法
查看>>
shell中$*和$@的区别
查看>>
log4cxx 的编译安装过程和使用
查看>>
简单邮件系统程序
查看>>
STL里的multimap使用详解
查看>>
STL 库其中的 std::string用法总结
查看>>
模态对话框的销毁过程与非模态对话的几种销毁方法
查看>>
C++实现http下载 && 24点计算编码风格
查看>>
memcached了解使用和常用命令详解
查看>>