1.并发不一定比串行更快 因为并发有线程创建和上下文切换的开销
2.java的并发采用内存共享模型
3.单线程中重排序不会影响到结果 但多线程中重排序可能会影响到结果
4.votaile变量 当线程A修改votatile变量会更加主内存发送信息给B线程 修改的值刷新到主内存 被通知的线程将本地内存的votaile值设为无效 读取主内存更新的值 但只能保证其线程的可见性 不能保证原子性
5.votaile相比锁是轻量级的同步 简易性和可收缩性 不会造成线程阻塞 也就不会造成死锁问题 性能更高 votaile读操作和非votaile读操作性能一样 但写操作比非votaile写操作性能更低 如果线程变量读操作远多于写操作 voatile提高比锁提高更低的效率 适用 状态标记 boolean 一次性发布 在整个项目运行中不会存在这个变量的非原子性操作
6.CAS和votaile是ReentantLock和concurrent包的基石
7.乐观锁和悲观锁 独占锁就是悲观锁 sychronized就是独占锁 让需要锁的线程挂起等待持有锁线程的
释放乐观锁的实质是采用CAS 在不加锁 假设不冲突的情况下完成某项操作 如果冲突则重试直到成功 为止内部实现是通过java native 方法(JNI) CAS的缺陷 第一 ABA问题 当某个值为A 修改为B 但又改为 A 通过加版本的方式解决(时间戳)第二 循环时间长开销大 通过CPU暂停指令解决 第三只能对一个 共享变量进行原子性操作 可以采用多个变量合并的方式
8.JMM的核心是happens_before 对于锁如果只有单个线程访问则可以将锁消除 votaile变量如果只有单个线程访问则可以将votaile变量当成普通变量
9.越是追求性能的处理器 内存模型设计就越弱
10.守护线程不能通过finally中的输出语句来判断程序执行完毕和内存资源的释放 因为程序执行完毕也不一定会执行try finally中的语句
11.在开启线程使最好给线程取好线程名 以便能够快速查找问题所在
12.在获取同步状态时 同步器会维护一个同步队列 获取同步状态失败的线程被加入到同步队列中进行自旋 获取同步状态成功的线程也就是同步队列的头结点出队或者被中断就会被唤醒自己结点的后继结点获取到同步状态
13.synchronized能隐式的重入锁 lock方法则不可以但可以显式再调用lock方法获取锁
14.排他锁 非公平锁可能造成线程饥饿 但减少了线程的切换 保证了更大的吞吐量 效率更高
15.读写锁 写锁是可重进入的排他锁 读锁是可重进入的共享锁 一个int变量记录读写锁的状态 读锁占
高16位写锁占低16位(1<<16) 读写锁 锁降级是否必要 答案是必要的因为 虽然获取读锁 有写锁获取时 则会被进入等待状态 但写锁获取之前可能有读锁获取到读锁 所以需要锁降级再次获取读锁进行数据同步
16.LockSupport类主要是用来阻塞和唤醒队列 ReentantLock内部主要是通过votaile技术和CAS技术实现同步 内部有同步器对同步队列和等待队列的操作 获取同步状态时 同步器会将获取失败的线程放入同步队列中 当同步队列头结点即获取到同步状态的被中断或者是被移除同步队列 会唤醒后继结点获取同步状态 LockSupport可以将线程在等待队列和同步队列之间切换
17.ConcurrentHashMap内部是segment类和HashEntry数组 Segment继承了ReentantLock类实现同步操作 将map中的数据分为多段 每段的长度会不一样 并加上锁 put方法是在segment上进行扩容加数据 采用的是哈希散列的方式再计算多段数据长度和时需要同步modCount方法判断容器是否有修改
18.ConcurrentLinkedQueue的入队方法永远返回的是true 不能通过入队方法判断是否入队成功
19.java是不能直接访问操作系统底层 只能通过本地方法访问 Unsafe是硬件级别的原子操作
第一 可以分配内存和释放内存 第二 阻塞和恢复线程(LockSupport) 第三CAS操作 第四 可以定位某对象的字段内存位置和修改对象字段值 即使是私有的
20.可以原子的更新引用类型 字段类 基本类型 数组 (AtomicReference)
21.CountDownLatch就是计数器当减到0时 await就不会阻塞当前线程了和CyclicBarrir的
22.Excharger类实现线程直接的交换数据
23.线程池的优点 第一 降低资源消耗 第二 缩短响应时间 第三提高对线程的管理性 线程的分配 调优 监控
24.线程池 当有个新任务进入线程池 没满则会创建新线程处理 如果线程池的基本数量的核心线程已经满了 会判断工作队列是否满了 没满则会放入阻塞队列中 如果满了 会让线程池创建新的线程处理这个任务 如果线程数量已经达到最大数量 则会执行饱和策略 默认是会报错 任务执行完了会去查看工作队列是否有任务如果有则会取出执行这个任务 如果工作队列空 并且当前线程池的线程数量大于基本数量则会被销毁 shutdown 和 shutdownNow方法 shutdownNow方法
25.建议使用有界的阻塞队列 需要有线程池的监控以方便知道线程各种情况 比如最大线程数
26.Excutors 方法fixThradPool CachedThreadPool是大小无界的线程池 适用于短期异步执行的小程序 负载较轻的服务器
27.FutureTask未启动 时调用futureTask.cancel会导致任务不会被执行 FutureTask启动时 futureTask.cancel(true)会以中断的方式使任务 任务已经执行完 futureTask.cancel(*)会返回false
28.for(;;)比如while(1)好的原因是指令少 不怎么占用寄存器 没有判断跳转
29.AQS实现的同步器于 ReentantLock ReentantReadWriteLock Semphore CountDownLatch FutureTask
30.多线程项目是比较难调试 所以需要打印好日志信息 以便及时查找问题所在 异常处理打印日志
和同步linux命令查看系统cup等相关的信息
31.ps -eLf}grep java -c 查看线程数是否增长
netstat -nat|grep 3306 -c 查看指定端口的数据库连接数
cat /proc/net/dev 查看网络流量
cat /proc/loadavg 查看系统平均负载
cat /proc/meminfo 查询系统内存使用情况
cat /proc/stat 查看CPU的利用率
32.根据任务类型或者任务的优先级进行不同线程池的处理
- Java 多线程高并发编程 笔记(一)
本篇文章主要是总结Java多线程/高并发编程的知识点,由浅入深,仅作自己的学习笔记,部分侵删. 一 . 基础知识点 1. 进程于线程的概念 2.线程创建的两种方式 注:public void run( ...
- Java 多线程:并发编程的三大特性
Java 多线程:并发编程的三大特性 作者:Grey 原文地址: 博客园:Java 多线程:并发编程的三大特性 CSDN:Java 多线程:并发编程的三大特性 可见性 所谓线程数据的可见性,指的就是内 ...
- JAVA多线程之并发编程三大核心问题
概述 并发编程是Java语言的重要特性之一,它能使复杂的代码变得更简单,从而极大的简化复杂系统的开发.并发编程可以充分发挥多处理器系统的强大计算能力,随着处理器数量的持续增长,如何高效的并发变得越来越 ...
- Java多线程与并发编程学习
一.线程三大特性 多线程有三大特性,原子性.可见性.有序性 1.1 什么是原子性 即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行.一个很经典的例子就是银行账户转账 ...
- Java 多线程高并发编程 笔记(二)
1. 单例模式(在内存之中永远只有一个对象) 1.1 多线程安全单例模式——不使用同步锁 public class Singleton { private static Singleton sin=n ...
- 已看1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉常用的Java API,包括集合框架、多线程(并发编程)、I/O(NIO)、Socket、JDBC、XML、反射等。[泛型]\
1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉常用的Java API,包括集合框架.多线程(并发编程).I/O(NIO).Socket.JDBC.XML.反射等.[泛型]\1* ...
- JAVA 多线程和并发学习笔记(三)
Java并发编程中使用Executors类创建和管理线程的用法 1.类 Executors Executors类可以看做一个“工具类”.援引JDK1.6 API中的介绍: 此包中所定义的 Execut ...
- JAVA多线程和并发基础面试问答(转载)
JAVA多线程和并发基础面试问答 原文链接:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-ans ...
- [转] JAVA多线程和并发基础面试问答
JAVA多线程和并发基础面试问答 原文链接:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-ans ...
随机推荐
- HTTP服务器(2)
import socket import re import multiprocessing def service_client(new_socket): """为这个 ...
- laravel insert 、save、update、create区别(总结二)
1.insert:插入数据时,需要维护 created_at 和 updated_at字段, 2.save:无论插入或者更新,会自动维护,无需手动操作 //插入: public function st ...
- Unexpected ConvertTo-Json results? Answer: it has a default -Depth of 2
Unexpected ConvertTo-Json results? Answer: it has a default -Depth of 2 问题 Why do I get unexpected C ...
- ModuleNotFoundError: No module named '_sqlite3'的解决办法:pipenv的用法
export PIPENV_VENV_IN_PROJECT=1pipenv --venvpipenv --where pipenv install -r requirements.txtpipenv ...
- Oracle 中使用正则表达式
Oracle使用正则表达式离不开这4个函数: 1.regexp_like select t3.cert_no from table_name t3 where regexp_like(t3.cert_ ...
- [windows菜鸟]C#中调用Windows API的技术要点说明
在.Net Framework SDK文档中,关于调用Windows API的指示比较零散,并且其中稍全面一点的是针对Visual Basic .net讲述的.本文将C#中调用API的要点汇集如下,希 ...
- [go]go并发
同步协程 通过睡眠方法 // 通过睡眠方式等待 time.Sleep(time.Second) <-time.NewTimer(time.Second).C <-time.After(ti ...
- 数据分析 - numpy 模块
numpy 概述 ▨ Numerical Python. 补充了python所欠缺的数值计算能力 ▨ Numpy是其他数据分析及机器学习库的底层库 ▨ Numpy完全标准C语言实现,运行效率充分 ...
- JVM内存模型及配置参数
JVM 分为堆.栈.方法区.程序计数器.本地方法栈 栈内存存放局部变量表.操作栈.动态链接.方法出口等信息 1. 局部变量表存放了编译期可知的各种基本数据类型(boolean.byte.char.s ...
- 使用Navicat为Oracle导入函数后函数显示红叉
上图是plsql中的截图 有可能是Navicat没有缓存过程,刷新试一试,不行的话,对导入的函数进行重新编译即可. 还发现一个问题是,Navicat导出的脚本里面,函数部分竟然没有参数和返回值,让我很 ...