【Java并发】JAVA并发编程实战-读书笔记1
2016-10-11 21:14
239 查看
从今天开始阅读《JAVA并发编程实战》这本书,并记录下自己阅读的记录。
首先感谢该书的原作者,几个外国的大神,也感谢韩锴、方妙两位译者。
程序在各自的进程中运行,相互分离,各自独立执行。由操作系统分配空间。
进程会通过一些原始的机制相互通信:Socket、信号处理、共享内存、信号量和文件。
线程有时被称为轻量级的进程。
同一个进程中的线程访问相同的变量,并从同一个堆中分配对象,但是如果没有机制来同步管理共享数据,就会出现一个线程修改另一个线程正在使用的数据,从而产生意外的结果。
在没有同步的情况下,多线程的各个操作的顺序是不可预测的。
1,线程A:获得了value,为0。
2,线程B:获得了value,为0。
3,线程A:执行了++,value为1。
4,线程B:执行了++,value为1。
5,线程A:得到了value为1。
6,线程B:得到了value为1。
正确的情况下,线程B获得的value应该是2。但是由于多线程的介入,指令执行的顺序不定,导致了错误的发生。
这里的问题在于,value++看似是一个语句,其实是分为三个步骤执行的,首先获得value的值,然后执行加1的操作,最后写回到value上。
这就是常见的并发危险:竞争条件(race condition)。当被多线程访问时,上面的方法能否返回不同的值,取决于CPU调度的顺序,这是我们不希望看到的。
允许多线程访问和修改相同的
b508
变量,给顺序编程模型引入了一些非顺序的因素。
简单的处理方法是,使用synchronized来修饰上面的方法,保证访问的唯一性。
在不使用同步的时候,编译器、硬件和运行时事实上对时间和活动的顺序是很随意的。
如果安全意味着什么坏事都没有发生过,活跃度关注是好事最终发生了。当一个活动进入了某种它永远无法在继续执行的状态时,活跃度失败就发生了。顺序程序中,粗心造成的死循环就是一种活跃度失败。
通过框架来访问应用程序中的组件,组件需要访问程序的状态,因此要求在所有的代码路径上,必须是线程安全的。
Timer用来调度一些稍后运行的任务,TimerTasks运行在由Timer管理的线程中,如果TimerTasks访问了其他应用程序正在访问的数据,那么不仅TimerTask需要线程安全,并且那些被同时访问的数据也要相应的保护措施。
编写线程安全的代码,本质上就是管理对状态的访问,而且通常是共享的、可变的状态。
所谓共享就是一个变量可以被多个线程访问,所谓可变就是变量的值在他的生命周期内是可以改变的。所以我们要在不可控制的并发中保护数据的安全性。
Java的首要同步机制就是synchronized关键字,他提供了独占锁。
如果多个线程访问同一个变量,有3种方法修复
1,不要跨线程共享变量。
2,使得状态变量为不可变。
3,在任何访问状态变量的时候使用同步。
一开始将一个类设计成线程安全的,比后期重新修复他更容易。
设计线程安全的类时,优秀的面向对象技术——封装、不可变性以及明确的不变约束——会给你提供诸多的帮助。
首先让你的代码正确,然后在让他跑的更快,总是一个良好的实践。
一个线程安全程序是完全由线程安全类构成的吗?不必要——完全由线程安全类构成的程序也未必是线程安全的。
首先感谢该书的原作者,几个外国的大神,也感谢韩锴、方妙两位译者。
程序在各自的进程中运行,相互分离,各自独立执行。由操作系统分配空间。
进程会通过一些原始的机制相互通信:Socket、信号处理、共享内存、信号量和文件。
线程有时被称为轻量级的进程。
同一个进程中的线程访问相同的变量,并从同一个堆中分配对象,但是如果没有机制来同步管理共享数据,就会出现一个线程修改另一个线程正在使用的数据,从而产生意外的结果。
在没有同步的情况下,多线程的各个操作的顺序是不可预测的。
private int value; public int getNext(){ return value++; }上面的方法在单线程时没有问题,如果出现了下面的执行情况。
1,线程A:获得了value,为0。
2,线程B:获得了value,为0。
3,线程A:执行了++,value为1。
4,线程B:执行了++,value为1。
5,线程A:得到了value为1。
6,线程B:得到了value为1。
正确的情况下,线程B获得的value应该是2。但是由于多线程的介入,指令执行的顺序不定,导致了错误的发生。
这里的问题在于,value++看似是一个语句,其实是分为三个步骤执行的,首先获得value的值,然后执行加1的操作,最后写回到value上。
这就是常见的并发危险:竞争条件(race condition)。当被多线程访问时,上面的方法能否返回不同的值,取决于CPU调度的顺序,这是我们不希望看到的。
允许多线程访问和修改相同的
b508
变量,给顺序编程模型引入了一些非顺序的因素。
简单的处理方法是,使用synchronized来修饰上面的方法,保证访问的唯一性。
在不使用同步的时候,编译器、硬件和运行时事实上对时间和活动的顺序是很随意的。
如果安全意味着什么坏事都没有发生过,活跃度关注是好事最终发生了。当一个活动进入了某种它永远无法在继续执行的状态时,活跃度失败就发生了。顺序程序中,粗心造成的死循环就是一种活跃度失败。
通过框架来访问应用程序中的组件,组件需要访问程序的状态,因此要求在所有的代码路径上,必须是线程安全的。
Timer用来调度一些稍后运行的任务,TimerTasks运行在由Timer管理的线程中,如果TimerTasks访问了其他应用程序正在访问的数据,那么不仅TimerTask需要线程安全,并且那些被同时访问的数据也要相应的保护措施。
编写线程安全的代码,本质上就是管理对状态的访问,而且通常是共享的、可变的状态。
所谓共享就是一个变量可以被多个线程访问,所谓可变就是变量的值在他的生命周期内是可以改变的。所以我们要在不可控制的并发中保护数据的安全性。
Java的首要同步机制就是synchronized关键字,他提供了独占锁。
如果多个线程访问同一个变量,有3种方法修复
1,不要跨线程共享变量。
2,使得状态变量为不可变。
3,在任何访问状态变量的时候使用同步。
一开始将一个类设计成线程安全的,比后期重新修复他更容易。
设计线程安全的类时,优秀的面向对象技术——封装、不可变性以及明确的不变约束——会给你提供诸多的帮助。
首先让你的代码正确,然后在让他跑的更快,总是一个良好的实践。
一个线程安全程序是完全由线程安全类构成的吗?不必要——完全由线程安全类构成的程序也未必是线程安全的。
相关文章推荐
- Java并发读书学习笔记(五)——任务执行
- Java并发读书学习笔记(十一)——原子变量与非阻塞同步机制
- Java并发读书学习笔记(七)——线程池
- Java并发读书学习笔记(四)——基础构建模块
- Java并发读书学习笔记(八)——避免活跃性危险
- Java并发读书学习笔记(六)——取消与关闭
- Java并发读书学习笔记(九)——性能与可伸缩性
- Java并发读书学习笔记(十)——显式锁
- Java线程学习笔记之并发集合类
- java并发编程实践笔记
- java并发编程实践 笔记(1)
- JAVA并发编程学习笔记之MCS队列锁
- thinking in java笔记 21 并发
- 最近仔细研究了一下Java的NIO以及线程并发,搞清了点思路,特作笔记如下(NIO篇)
- JAVA并发编程学习笔记之ReentrantLock
- 最近仔细研究了一下Java的NIO以及线程并发,搞清了点思路,特作笔记如下(NIO篇)
- 读书笔记----THINK IN JAVA
- java学习——java高级特性,线程,并发 笔记
- EBS中Java并发程序笔记(1)
- java并发编程实践笔记