耘朵
一只不务正业的程序媛
Toggle navigation
耘朵
主页
归档
标签
多线程并发
java
线程
2021-11-02 09:14:36
181
0
0
admin
java
线程
## 死锁 两个或两个以上的线程在执行过程中,因争夺资源而造成的互相等待的现象,无外力作用将互相等待下去 **发生必要条件** - 互斥条件 - 请求和保持条件 - 不剥夺条件 - 环路等待条件 **发生死锁代码** ``` package com.csyd.concurrency.example.deadLock; import lombok.extern.slf4j.Slf4j; @Slf4j public class DeadLock implements Runnable{ public int flag = 1; private static Object o1 = new Object(), o2 = new Object(); @Override public void run() { log.info("flag:{}", flag); if (flag == 1){ //排他性 synchronized (o1){ try { Thread.sleep(500); }catch (Exception e){ e.printStackTrace(); } //请求保持,锁定了o1继续请求o2 synchronized (o2){ log.info("1"); } } } if (flag == 0){ //排他性 synchronized (o2){ try { Thread.sleep(500); }catch (Exception e){ e.printStackTrace(); } //请求保持,锁定了o2继续请求o1 synchronized (o1){ log.info("0"); } } } } public static void main(String[] args) { DeadLock td1 = new DeadLock(); DeadLock td2 = new DeadLock(); td1.flag = 1; td2.flag = 0; new Thread(td1).start(); new Thread(td2).start(); } } ``` ## 多线程并发最佳实践 1. 使用本地变量 2. 使用不可变类 3. 最小化锁的作用域范围:S=1/(1-a+a/n) a并行计算部分所在的比例 n并行处理的节点个数 S加速比 4. 使用线程池的Executor,而不是直接new Thread执行 5. 宁可使用同步也不要使用线程的wait和notify 6. 使用BlockingQueue实现生产-消费模式 7. 使用并发集合而不是加了锁的同步集合 8. 使用Semaphore创建有界的访问 9. 宁可使用同步代码块,也不实用同步的方法 10. 避免使用静态变量 ## Spring与线程安全 **原因** - Spring bean: singleton(单例)、prototype(每次定义都会创建新的对象) - 无状态对象,自身无状态,就不会因为多个线程调度而改变自身状态 ## HashMap与ConcurrentHashMap hashmap是数组和链表结合 HashMap寻址方式:插入或读取时,hashmap要将他的key按照一个规则计算出hash值,并对数组长度进行取模查找数组中的index,他的线程不安全可能在resize,rehash改变数组大小的时候发生死循环 concurrenthashmap是数组和链表结合,最外层是个Segment数组 concurrenthashmap寻址方式:根据hash码高sshift位决定Segment数组的index,再根据hash码决定hashentry数组的index **HashMap与ConcurrentHashMap区别** HashMap线程不安全,ConcurrentHashMap线程安全 HashMap允许key和value为空,ConcurrentHashMap不允许 HashMap不允许Itrator遍历的同时,通过HashMap修改,ConcurrentHashMap允许 java8中ConcurrentHashMap引入了红黑树提高遍历
上一篇:
POI导出Excel优化速度方式
下一篇:
线程池
0
赞
181 人读过
新浪微博
微信
腾讯微博
QQ空间
人人网
文档导航