开发必会系列:《Java多线程编程实战》读书笔记
一 基础
进程是程序向操作系统申请资源(如内存空间和文件句柄)的基本单位。线程是进程中可独立执行的最小单位。
在Java平台中创建一个线程就是创建一个Thread类(或其子类)的实例。
运行一个线程实际上就是让Java虚拟机执行该线程的run方法,从而使相应线程的任务处理逻辑代码得以执行。
Thread类的两个常用构造器是:Thread() 和 Thread(Runnable target) 。(Thread的run方法里会判断target !=null,所以Tread类实际上是Runnable接口的一个实现类。)
如:
Thread testThread = new TestThread(); class TestThread extends Thread Thread testThread = new Thread(new TestThread());
class TestThread implements Runnable
testThread.start(),class里重写run方法,run里是自己的逻辑代码。run方法总是由Java虚拟机直接调用,我们能直接调,但这蠢事没人干。
我们一般使用第二种方法创建线程,因为它基于组合,比继承灵活。但是,第二种创建方式意味着多个线程实例可以共享同一个Runnable实例,这可能因此竞态和线程安全相关问题。
run方法执行结束,线程占用的资源会被Java虚拟机回收。(线程池的原理是让run方法永远运行不完么)
由于同一段代码可以被多个线程执行,因此当前线程是相对的。
线程的优先级属性本质上只是一个给线程调度器的提示信息。
Java中的线程分为守护线程和用户线程。
用户线程会阻止Java虚拟机的正常停止,即一个Java虚拟机只有在其所有用户线程都运行结束的情况下才能正常停止。如果用kill命令杀Java虚拟机进程,那即使用户线程也无法阻止Java虚拟机的停止。
而守护线程不会影像Java虚拟机的正常停止,即应用程序中的守护线程在运行也不影响Java虚拟机的正常停止。因此,守护线程通常用于执行一些重要性不高的任务,例如用于监视其他线程的运行情况。
常用方法:run 虚拟机调用;start 一个thread实例的start方法只能被调一次,多了会异常;join 线程a调用线程b的join方法,线程a的运行会被暂停,直到线程b运行结束;yield 使当前线程可能主动放弃对处理器的占用,导致当前线程被暂停,相当于对程序调度器说:我不急,有人用就先让别人用,真没人用就我用; sleep 使当前线程休眠指定时间。
Java虚拟机启动的时候会创建一个main线程,该线程负责执行Java程序的入口方法(main方法)。web应用中的servlet类的doget、dopot方法也总是由确定的线程负责执行的。垃圾回收有专门的线程。动态编译有专门的线程。在多线程编程中,弄清楚一段代码具体是由哪个或哪种线程去负责执行的这点很重要,这关系到性能、线程安全等问题。
线程的生命周期共有6种状态,new,runnable,blocked,waiting,timed_waiting,terminated。
对线程进行监视的主要途径是获取并查看程序的线程转储(Thread Dump),它包含了获取这个线程转储的那一刻该程序的线程信息。
从软件的角度来说,并发就是在一段时间内以交替的方式去完成多个任务,而并行就是以齐头并进的方式去完成多个任务。软件要以并发的方式去完成几个任务往往需要借助多个线程(而不是一个线程)。
从硬件的角度来说,一个处理器一次只能运行一个线程,处理器是通过时间片分配实现同一段时间运行多个线程,因此一个处理器可以实现并发,而并行需要多个处理器。
竞态:结果有时对,有时错,正确性和时间有关。比如多个线程取到相同的值,就是因为一个线程对共享值的更新覆盖了其他线程对该值的更新。所以,竞态往往伴随着读取脏数据,和丢失更新。
synchronized关键字会使其修师的方法在任一时刻只能够被一个线程执行。
一个类如果不是线程安全的,我们就说它在多线程环境下直接使用存在线程安全问题。线程安全问题概况来说表现为3个方面:原子性、可见性和有序性。
原子性的不可分割:线程执行某个共享变量,对其他线程来说,该操作要么已经执行结束要么尚未发生。
Java有两种方式实现原子性,一种是使用锁,另一种是利用处理器提供的专门CAS执行。CAS与锁本质相同,差别在于锁在软件层实现,CAS在硬件层实现(处理器和内存)。
Java语言除了long和double,其他基本类型的写操作都是原子操作,有Java虚拟机具体实现。
原子性指操作不能被中断,可见性指多线程之间对共享变量的修改是否进行了处理器的缓存同步而被其他线程实时读取到,有序性指源码顺序和处理器执行顺序可能不一样,反正这三个在Java中都可以通过volatile修饰来避免线程安全问题。
我不想做笔记了,用别人的吧。Java多线程编程实战指南(核心篇)读书笔记;
补充一点——Java多线程程序的调试与测试:
针对多线程程序的测试框架和工具还没有,而junit也不支持测试多线程。能用静态检查工具FindBugs;但它会有误报。
或者直接代码审查;
OpenJDK下有一个多线程程序单元测试的试验项目:JCStress;
开发必会系列:《Java多线程编程实战》读书笔记的更多相关文章
- Spring 实战 第4版 读书笔记
第一部分:Spring的核心 1.第一章:Spring之旅 1.1.简化Java开发 创建Spring的主要目的是用来替代更加重量级的企业级Java技术,尤其是EJB.相对EJB来说,Spring提供 ...
- 深入浅出MySQL 数据库开发、优化与管理维护(第2版) -- 读书笔记 -- 基础篇
1.切换数据库 use blog; 2.显示当前数据库 所有的表. show tables; +----------------+ | Tables_in_blog | +------------ ...
- Spring实战第4版PDF下载含源码
下载链接 扫描右侧公告中二维码,回复[spring实战]即可获取所有链接. 读者评价 看了一半后在做评论,物流速度挺快,正版行货,只是运输过程有点印记,但是想必大家和你关注内容,spring 4必之3 ...
- Spring实战(第4版).pdf - 百度云资源
http://www.supan.vip/spring%E5%AE%9E%E6%88%98 Spring实战(第4版).pdf 关于本书 Spring框架是以简化Java EE应用程序的开发为目标而创 ...
- Spring实战第六章学习笔记————渲染Web视图
Spring实战第六章学习笔记----渲染Web视图 理解视图解析 在之前所编写的控制器方法都没有直接产生浏览器所需的HTML.这些方法只是将一些数据传入到模型中然后再将模型传递给一个用来渲染的视图. ...
- Spring实战第五章学习笔记————构建Spring Web应用程序
Spring实战第五章学习笔记----构建Spring Web应用程序 Spring MVC基于模型-视图-控制器(Model-View-Controller)模式实现,它能够构建像Spring框架那 ...
- Spring实战第四章学习笔记————面向切面的Spring
Spring实战第四章学习笔记----面向切面的Spring 什么是面向切面的编程 我们把影响应用多处的功能描述为横切关注点.比如安全就是一个横切关注点,应用中许多方法都会涉及安全规则.而切面可以帮我 ...
- 将Spring实战第5版中Spring HATEOAS部分代码迁移到Spring HATEOAS 1.0
最近在阅读Spring实战第五版中文版,书中第6章关于Spring HATEOAS部分代码使用的是Spring HATEOAS 0.25的版本,而最新的Spring HATEOAS 1.0对旧版的AP ...
- ASP.NET MVC开发必看系列
一.关于HTTP协议的那些事 这可以说我们开发WEB程序的空气,推荐不断温故知新! HTTP协议 (一) HTTP协议详解 HTTP协议 (二) 基本认证 HTTP协议 (三) 压缩 HTTP协议 ( ...
- Spring实战 (第3版)——AOP
在软件开发中,分布于应用中多处的功能被称为横切关注点.通常,这些横切关注点从概念上是与应用的 业务逻辑相分离的(但是往往直接嵌入到应用的业务逻辑之中).将这些横切关注点与业务逻辑相分离正是 面向切面编 ...
随机推荐
- 浅谈 2-SAT
SAT 是适定性(Satisfiability)问题的简称.一般形式为 k - 适定性问题,简称 k-SAT.而当 \(k>2\) 时该问题为 NP 完全的.所以我们只研究 \(k=2\) 的情 ...
- Rancher 2.x 安装
Rancher 是一个容器管理平台.Rancher 简化了使用 Kubernetes 的流程. 下面记录一下手动安装Rancher的步骤 1. 部署 Rancher Server 执行以下命令即可( ...
- zTree如何实现模糊查找实战
1.说明 最近在研究zTree树控件.过程中涉及到了实现模糊查找结点的功能,特此分享一下. 有关zTree的有关介绍和使用,请访问其官网:zTree -- jQuery 树插件 本文假设你已经比较熟悉 ...
- Java并发编程实例--1.创建和运行一个线程
从这一篇开始写Java并发编程实例,内容都翻译整理自书籍:<Java 7 Concurrency Cookbook> 谈到线程,无法逃避的一个问题就是: 并发(concurrency)和并 ...
- 【树莓派】拷贝系统到新SD卡(系统备份/部署到另一台树莓派上)适用ubuntu 20.04.3
本教程适用ubuntu 20.04.3 其他版本也大同小异.这种方法能更快的将系统部署下去,如果重新安装一遍加上各种配置相信你会比较疯狂即使做了自动化脚本! 一.树莓派sd卡拷贝 把旧SD卡插入树莓派 ...
- 在vue项目中使用scss语法的准备步骤
在vue项目中使用scss语法的准备步骤 个人总结: 在项目根目录cmd控制台中使用以下命令行,安装vue项目中使用scss的相关依赖; 在["项目根目录/build/webpack.bas ...
- auth模块的一些方法
auth模块 auth模块是cookie和session的升级版,auth模块是对登录认证方法的一种封装,之前我们获取用户输入的用户名及密码后需要自己从user表里查询有没有用户名和密码符合的对象,而 ...
- python基础安装虚拟环境
1.pip install virtualenv或者pip3 install virtualenv 2.在要存放虚拟环境的地方创建一个venv文件夹,用来存放所有创建的虚拟环境,方便查找与管理 3.m ...
- Vue.beforeEach is not a function报错
使用导航守卫改变页面的title时报错了,明明在beaforeEach的参数中写了箭头函数也报下面的错误 后面发现我的问题在于直接导出了export.default new Router({--})中 ...
- TCP的链接和断开_wireShark实践
目录 准备 TCP连接的三次握手 WireShark验证 TCP的四次挥手 WireShark验证 状态解释 其他的 # 概述 终于到了学习总结时间了 准备 TCP连接的三次握手 转自https:/ ...