博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
常用多线程方法
阅读量:4957 次
发布时间:2019-06-12

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

可重入锁

​ ReentrantLock类、synchronized关键字,属于悲观锁。

​ 可重入锁,即递归锁。指在同一线程内,外层函数获得锁之后,内层递归函数仍然可以获得该锁。

​ 作用:防止在同一线程中多次获取锁而导致死锁发生。

自旋锁

​ java.util.concurrent.atomic包下的AtomicReference等原子类的使用,属于乐观锁。

​ 当一个线程在获取锁的时候,如果锁已经被其他线程获取,那么该线程将循环等待,然后不断的判断,锁是否能够被成功获取,直到获得锁才会退出循环。

​ 获取锁的线程一直处于活动状态,但是并没有执行任何有效的任务,使用这种锁会造成busy-waiting。所以需要增加一些退出忙等的方法。

​ 实现:CAS。

​ 缺点:CPU可能长时间极高,不释放线程,不公平造成其他“线程饥饿”问题。CAS操作可能存在ABA的问题,就是说:假如一个值原来是A,变成了B,又变成了A,那么CAS检查时会发现它的值没有发生变化,但是实际上却变化了,如果线程不关心变量中途如何变化,那么这个不是什么问题;如果有些操作会依赖于对象的变化过程,此时的解决思路一般就是使用版本号,在变量前面追加上版本号,每次变量更新的时候把版本号加一,那么A-B-A 就会变成1A - 2B - 3A。

​ 例如:原子引用,以无锁方式访问共享资源

public class AtomicRefTest {    public static void main(String[] args) throws InterruptedException {        AtomicReference
atomRef = new AtomicReference<>(new Integer(1000)); List
list = new ArrayList<>(); for (int i = 0; i < 1000; i++) { Thread thread = new Thread(new Task(atomRef), "Thread-" + i); list.add(thread); thread.start(); } for (Thread thread : list) { thread.join(); } System.out.println(atomRef.get()); // 打印2000 }}class Task implements Runnable { private AtomicReference
atomRef; Task(AtomicReference
atomRef) { this.atomRef = atomRef; } @Override public void run() { while (true) { //自旋操作 Integer oldV = atomRef.get(); if (atomRef.compareAndSet(oldV, oldV + 1)) // CAS操作 break; } }}

上述示例,最终打印“2000”。

​ 该示例并没有使用锁,而是使用自旋+CAS的无锁操作保证共享变量的线程安全。1000个线程,每个线程对金额增加1,最终结果为2000,如果线程不安全,最终结果应该会小于2000。

​ 总结:使用CAS的套路:

AtomicReference atomRef = new AtomicReference<>(new Object());Object oldCache = atomRef.get();// 对缓存oldCache做一些操作Object newCache  =  someFunctionOfOld(oldCache); // 如果期间没有其它线程改变了缓存值,则更新boolean success = atomRef.compareAndSet(oldCache , newCache);

转载于:https://www.cnblogs.com/aric2016/p/11494176.html

你可能感兴趣的文章
Binding object to winForm controller through VS2010 Designer(通过VS2010设计器将对象绑定到winForm控件上)...
查看>>
Spring Boot实战笔记(二)-- Spring常用配置(Scope、Spring EL和资源调用)
查看>>
第二章:webdriver 控制浏览器窗口大小
查看>>
【动态规划】流水作业调度问题与Johnson法则
查看>>
Python&Selenium&Unittest&BeautifuReport 自动化测试并生成HTML自动化测试报告
查看>>
活现被翻转生命
查看>>
POJ 1228
查看>>
SwaggerUI+SpringMVC——构建RestFul API的可视化界面
查看>>
springmvc怎么在启动时自己执行一个线程
查看>>
流操作的规律
查看>>
Python基础学习15--异常的分类与处理
查看>>
javascript运算符的优先级
查看>>
React + Redux 入门(一):抛开 React 学 Redux
查看>>
13位时间戳和时间格式化转换,工具类
查看>>
vue router-link子级返回父级页面
查看>>
C# 通知机制 IObserver<T> 和 IObservable<T>
查看>>
Code of Conduct by jsFoundation
查看>>
div 只显示两行超出部分隐藏
查看>>
C#小练习ⅲ
查看>>
电源防反接保护电路
查看>>