Netty的并发编程实践1:正确使用锁
来源:互联网 发布:selenium java 编辑:程序博客网 时间:2024/05/18 01:47
很多刚接触多线程编程的开发者,虽然意识到了并发访问可变变量需要加锁,但是对于锁的范围、加锁的时机和锁的协同缺乏认识,往往会导致出现一些问题。下面笔者就结合Netty的代码来讲解下这方面的知识。
打开ForkJoinTask,我们学习一些多线程同步和协作方面的技巧。首先是当条件不满足时阻塞某个任务,直到条件满足后再继续执行,代码如图21-4所示。
重点看框线中的代码,首先通过循环检测的方式对状态变量status进行判断,当它的状态大于等于0时,执行wait(),阻塞当前的调度线程,直到status小于0,唤醒所有被阻塞的线程,继续执行。这个方法有以下三个多线程的编程技巧需要说明。
图21-4 多线程协作
(1)wait方法用来使线程等待某个条件,它必须在同步块内部被调用,这个同步块通常会锁定当前对象实例。下面是这个模式的标准使用方式。
synchronized(this)
{
While(condition)
Object.wait;
......
}
(2)始终使用wait循环来调用wait方法,永远不要在循环之外调用wait方法。这样做的原因是尽管并不满足被唤醒条件,但是由于其他线程调用notifyAll()方法会导致被阻塞线程意外唤醒,此时执行条件并不满足,它将破坏被锁保护的约定关系,导致约束失效,引起意想不到的结果。
(3)唤醒线程,应该使用notify还是notifyAll?当你不知道究竟该调用哪个方法时,保守的做法是调用notifyAll唤醒所有等待的线程。从优化的角度看,如果处于等待的所有线程都在等待同一个条件,而每次只有一个线程可以从这个条件中被唤醒,那么就应该选择调用notify。
当多个线程共享同一个变量的时候,每个读或者写数据的操作方法都必须加锁进行同步,如果没有正确的同步,就无法保证一个线程所做的修改被其他线程共享。未能同步共享变量会造成程序的活性失败和安全性失败,这样的失败通常是难以调试和重现的,它们可能间歇性地出问题,可能随着并发的线程个数增加而失败,也可能在不同的虚拟机或者操作系统上存在不同的失败概率。因此,务必要保证锁的正确使用。下面这个案例,就是个典型的错误应用。
int size = 0;
public synchronized void increase()
{
size++;
}
public int current()
{
Return size;
}
- Netty的并发编程实践1:正确使用锁
- Netty的并发编程实践2:volatile的正确使用
- 并发编程实践四:实现正确和高效的锁
- Netty的并发编程实践5:不要依赖线程优先级
- Netty的并发编程实践4:线程安全类的应用
- Netty的并发编程实践3:CAS指令和原子类
- netty并发编程
- netty并发编程模型
- 并发编程【正确使用 Volatile 变量】
- 并发编程【正确使用 Volatile 变量】
- Java并发编程实践之Callable,Future,RutureTask的使用
- Netty系列之Netty并发编程分析
- JAVA并发编程实践- 线程的优点
- 看《Java并发编程实践》的笔记
- <Java 并发编程实践>读书笔记 --- 内部锁
- 1、java并发编程实践(1)
- java并发编程实践 笔记(1)
- Java并发编程1:实践基础
- SDN控制器 之南向网络控制技术
- 第40讲--项目九--污损的单据
- ios模拟器不弹出解决方法
- 寄存器重命名
- 第六题 P035
- Netty的并发编程实践1:正确使用锁
- JS引用路劲为什么在前面加上两个斜杠
- 转载---进程与线程的一个简单解释
- Invalid message received with signature 18245
- cui-----Hadoop动态添加删除datanode及tasktracker【需要整理】
- QT程序占用内存过高
- 初识Tkinter
- POJ2689 Prime Distance 素数距离
- 定义MySharedPreferencesFor类