Java多线程学习笔记之一线程基础
1、进程与线程
1.1 进程:是正在运行中的程序的实例,一个运行中idea就是一个进程。进程有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。
1.2 线程:是程序中一个单一的顺序控制流程。是进程中可独立执行的最小单位。
1.3 两者关系:进程申请资源,线程利用这些资源,具体执行任务。一个进程可以包含多个线程,同一进程中线程共享该进程中资源。
2、线程的创建、启动、运行(见代码)
2.1 创建
2.1.1 以继承Thread类的方式创建
2.1.2 以实现Runable接口的方式创建
2.1.3 两种创建方式的区别:继承Thread类的方式是基于继承的方法,实现Runable接口的方式是基于接口的方法。 接口实现的耦合性相比于继承而言更低,也更加灵活,可以多个线程共享同一个Runnable实例。
2.2 启动:Thread类的start()方法的作用是启动调用的线程,但start()方法完成,并不意味着该线程会立即执行,可能会稍后被执行, 也可能永远不会被执行,start()方法完成后的线程处于RUNNABLE状态中的READY状态。
2.3 运行:即线程此时正在执行Run()方法中的逻辑
public class CreateThread {
public static void main(String[] args) {
//创建线程
Thread createThread1 = new CreateThread1();
//启动线程
createThread1.start();
System.out.println("当前执行的线程"+Thread.currentThread().getName());
//创建线程
Thread createThread2 = new Thread(new CreateThread2());
//启动线程
createThread2.start();
}
}
//定义Thread类的子类
class CreateThread1 extends Thread{
@Override
public void run() {
System.out.println("以继承Thread类的方式创建的线程"+Thread.currentThread().getName());
}
}
//定义实现Runnable接口的类
class CreateThread2 implements Runnable{
@Override
public void run() {
System.out.println("以实现Runable接口的方式创建的线程"+Thread.currentThread().getName());
}
}
3、线程属性
表1-线程属性
| 属性 | 属性类型 | 只读属性 | 用途 | 备注 |
| 编号(ID) | long | 是 | 标识不同的线程 | 改编号的唯一性在Java虚拟机的一次运行中有效 |
| 名称(Name) | String | 否 | 用于使用人员区别不同线程 | 设置该属性便于调试和问题定位 |
| 线程类别(Daemon) | boolean | 否 |
true表示守护线程, false表示用户线程 |
守护线程:不会影响Java虚拟机的正常停止 用户线程:一个Java虚拟机必须在其所有用户线程都运行结束的情况下才能正常停止 默认值与相应父线程的该属性值相同,为此属性赋值必须在start()方法执行之前 |
| 优先级(Priority) | int | 否 | 用于表示应用程序希望哪个线程优先执行 | Java定义了1-10的10个优先级,默认值为5,不推荐设置优先级 |
4、线程的层次
Java中的线程并不是孤立的,相互之间存在一定的联系。假设线程M的执行逻辑中创建了线程N,那么线程M就是线程N的父线程,线程N是线程M的子线程。这种父子关系是相对的,线程N是线程M的子线程,但若在线程N的执行逻辑中创建了线程X,那么线程N又是线程X的父线程。这种层次关系是一种弱关联关系,父子线程之间的运行时相互不影响的,它们的生命周期状态也是没有必然关系的。
5、线程的生命周期状态
NEW:一个创建而未启动的线程处于该状态。因为一个线程实例只能够被启动一次,所以一个线程只能处于该状态一次。
RUNNABLE:该状态可以被看做复合状态,包括READY和RUNNING两个子状态。READY状态下的线程是活跃线程,随时有可能运行,执行 Start()方法后执行之前的线程处于该状态。RUNNING状态的线程是正在执行代码逻辑的线程。
BLOCKED:一个线程发起一个阻塞式I/O操作后,或者申请一个由其他线程持有的独占资源时,相应线程会处于该状态,此时该线程不会占用处理器资源。当阻塞式I/O操作完成后,或者线程获得了其申请的资源,该线程的状态就会转换为RUNNABLE.
WAITTING:等待其它线程执行另外一些特定操作的状态。Object.wait()、Thread.join()和LockSupport.park()方法会使线程处于该状态。同时,Object.notify()/notifyAll()和LockSupport.unpark(Object)会使线程由该状态转为RUNNABLE状态。
TIMED_WAITING:该状态是有时间限制的等待状态,当其它线程没有在指定时间内执行完该线程所期望的特定操作时,该线程的状态就会自动转换为RUNNABLE。
TERMINATED:已经执行结束的线程处于该状态。
一个线程在其整个生命周期中,只可能有一次处于NEW和TERMINATED状态,其它状态可能多次出现,并会相互转换。
6、Thread类的常用方法
表2-Thread类的常用方法
| 方法 | 功能 | 备注 |
| static Thread currentThread() | 返回当前代码执行线程 | 同一段代码,不同时刻调用此方法返回值可能不同 |
| void run() | 用于实现线程的任务处理逻辑 | 一般有Java虚拟机调用,不建议程序调用 |
| void start() | 启动线程 | 一个Thread实例的只能调用一次start()方法 |
| void join() | 等待相应线程运行结束 | 若线程M调用线程N的join方法,那么线程M会被暂停,知道线程N运行完毕 |
| static void yield() | 使当前线程主动放弃其对处理器的占用,这可能导致当前线程被停止 | 这个方法是不可靠的 |
| static void sleep(long millis) | 使当前线程休眠指定时间 | 入参为毫秒 |
7、线程的监视
对线程的监视主要途径是获取并查看程序的线程转储。一个程序的线程转储包含了获取这个线程转储那一刻该程序的线程信息
获取方法:JDK自带工具:jstack、jvisualvm、jmc。命令:kill -3 PID
Java多线程学习笔记之一线程基础的更多相关文章
- java多线程学习笔记——详细
一.线程类 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...
- JAVA多线程学习笔记(1)
JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...
- Java多线程学习笔记(一)——多线程实现和安全问题
1. 线程.进程.多线程: 进程是正在执行的程序,线程是进程中的代码执行,多线程就是在一个进程中有多个线程同时执行不同的任务,就像QQ,既可以开视频,又可以同时打字聊天. 2.线程的特点: 1.运行任 ...
- Java多线程学习笔记
进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...
- java 多线程学习笔记
这篇文章主要是个人的学习笔记,是以例子来驱动的,加深自己对多线程的理解. 一:实现多线程的两种方法 1.继承Thread class MyThread1 extends Thread{ public ...
- Java多线程学习笔记--生产消费者模式
实际开发中,我们经常会接触到生产消费者模型,如:Android的Looper相应handler处理UI操作,Socket通信的响应过程.数据缓冲区在文件读写应用等.强大的模型框架,鉴于本人水平有限目前 ...
- Java 多线程学习笔记:生产者消费者问题
前言:最近在学习Java多线程,看到ImportNew网上有网友翻译的一篇文章<阻塞队列实现生产者消费者模式>.在文中,使用的是Java的concurrent包中的阻塞队列来实现.在看完后 ...
- 最全java多线程学习总结1--线程基础
<java 核心技术>这本书真的不错,知识点很全面,翻译质量也还不错,本系列博文是对该书中并发章节的一个总结. 什么是线程 官方解释:线程是操作系统能够进行运算调度的最小单位,包含 ...
- java多线程学习笔记(三)
java多线程下的对象及变量的并发访问 上一节讲到,并发访问的时候,因为是多线程,变量如果不加锁的话,会出现“脏读”的现象,这个时候需要“临界区”的出现去解决多线程的安全的并发访问.(这个“脏读”的现 ...
随机推荐
- PBN飞越转弯Flyover衔接DF航段保护区组图
PBN飞越转弯Flyover衔接DF航段,是飞越转弯中最常用的形态. Flyover-DF保护区叠加图: Flyover-DF保护区分解图:
- webpack3新特性简介
6月20号webpack推出了3.0版本,官方也发布了公告.根据公告介绍,webpack团队将未来版本的改动聚焦在社区提出的功能需求,同时将保持一个快速.稳定的发布节奏.本文主要依据公告内容,简单介绍 ...
- [转]TFS常用的命令行详解
本文转自:http://blchen.com/tfs-common-commands/ 微软的TFS和Visual Studio整合的非常好,但是在开发过程中,很多时候只用GUI图形界面就会发现一些复 ...
- MVC用非Entity Framework将数据显示于视图(二)
这篇<MVC用非Entity Framework将数据显示于视图> http://www.cnblogs.com/insus/p/3364235.html 也算是MVC视图显示数据库的数据 ...
- textarea赋值时换行符无效的解决方法
//替换字符串中的换行符为br var Content = JSON.stringify(txt); Content = Content.replace(/\\n/g, '<br />') ...
- 自己写一个java的mvc框架吧(二)
自己写一个mvc框架吧(二) 自己写代码的习惯 写一个框架吧,如果这个框架会用到一些配置上的东西,我自己习惯是先不用考虑这个配置文件应该是怎样的,什么形式的,先用一个java对象(比如叫 Config ...
- Java JDBC的基础知识(二)
在我的上一篇Java JDBC的基础知识(一)中,最后演示的代码在关闭资源的时候,仅仅用了try/catch语句,这里是有很大的隐患的.在程序创建连接之后,如果不进行关闭,会消耗更多的资源.创建连接之 ...
- 存储过程TYPE类型参数调试
当我们写完一段存储过程后,必然需要调试运行一下写的代码是否能成功运行,当参数是字符,数字或日期时,可以直接在测试窗口输入值.但是类型如果是定义好的TYPE,就无法简单的输入. 一.自定义TYPE TY ...
- 集合框架三(List和Set的补充(不加泛型))
List List存放的元素有序,可重复 List list = new ArrayList(); list.add("123"); list.add("456" ...
- layui的checkbox示例
1.html页面: var isSkipcheckbox = ''; if (appOptions.isSkip != "0") { isSkipcheckbox = 'check ...