《MySql面试专题》
《MySql性能优化的21个最佳实践》
《MySQL高级知识笔记》
文中展示的资料包括:**《MySql思维导图》《MySql核心笔记》《MySql调优笔记》《MySql面试专题》《MySql性能优化的21个最佳实践》《MySq高级知识笔记》**如下图
关注我,点赞本文给更多有需要的人
► 简介
► 概念
►Java内存模型:Happens-before 关系
► 标准同步功能
► 安全发布
► 对象不可变
► 线程Thread类
► 线程的活跃度:死锁与活锁
► java.util.concurrent包
第1节 简介
所谓并发编程是指在一台处理器上“同时”处理多个任务。并发是在同一实体上的多个事件。这段是从百度百科找到的解释, 而我的解释, 你所写的任何一行代码, 它的执行都是用线程来运行的, 也就是说并发编程直接决定了你系统性能运行情况, 能让你的系统起飞, 也能让你的系统性能变成蜗牛。
第2节 概念
从JDK的最低版本开始,Java就支持了线程和锁等关键并发概念。那么这些概念务必记到你脑海深处,哈哈.
前提条件
当多个线程对共享资源执行一系列操作时, 它们会对竞争共享资源, 每个线程的操作顺序不一样, 会导致多个不可预期的操作结果。比如以下的代码就为非线程安全的,其中 value
可以多次初始化,因为 if(value==null)
做了null 判断, 然后初始化的, 延迟初始化的字段不是原子的:
class JamesLazy {
private volatile T value;
T get() {
if (value == null)//这里做了null判断, 延迟初始化的字段它不是原子的
value = initialize();
return value;
}
}
数据竞争
当两个或多个线程在没有同步的情况下尝试访问相同的非final变量时,就会发生数据竞争。不使用同步可能导致你的所有操作对其它线程是不可见的,因此可以读取过时数据,但若反过来可能会产生无限循环,损坏的数据结构或不准确的计算等后果。此代码可能会导致无限循环,因为读者线程可能永远不会观察到写入器线程所做的更改:
class JamesWaiter implements Runnable {
private Boolean shouldFinish;
void finish() {
shouldFinish = true;
}
public void run() {
long iteration = 0;
while (!shouldFinish) {
iteration++;
}
System.out.println("完成后的结果: " + iteration);
}
}
class JamesDataRace {
public static void main(String[] args) throws InterruptedException {
JamesWaiter waiter = new JamesWaiter();
Thread waiterThread = new Thread(waiter);
waiterThread.start();
waiter.finish();
waiterThread.join();
}
}
运行结果为:
第3节 Java内存模型:Happens-before 关系
Java内存模型是根据读取和写入字段以及在监听器上同步等操作定义的。可以通过Happens-before关系对操作进行排序,一般用于推断线程何时看到另一个线程的操作结果,以及用来分析同步的程序构成状况。
在下图中,Thread 1的 ActionX
操作在 ActionY
操作之前就调用了,因此在 Thread2
中所有操作 ActionY
的右侧业务操作时, 将会看到Thread 1中Action X前的所有操作。
第4节 标准同步功能
synchronized关键字
synchronized
关键字用于防止不同的线程同时执行相同的代码块, 其实就是指这个代码块只被一个线程执行。当线程A获得synchronized锁后,只有线程A访问synchronized代码块,是一种独占式模式操作, 例如: 13号技师被王根基同学带进屋后,王根基同学在门上挂了把锁, 其它线程得等待, 保证了13号技师只能与王根基(线程)进行业务操作 ,不难看出这个操作原子操作(只有王根基线程操作13号技师)。此外,它保证其它线程在获取相同的锁之后将观察正在操作线程的结果,何时释放锁。
class JamesAtomicOperation {
private int counter0 ;
private int counter1 ;
void increment(){
synchronized(this){
counter0 ++ ;
counter1 ++ ;
}
}
}
synchronized
关键字可以在方法级来指定。
锁是可重入的,因此如果线程已经拥有锁,可以再次成功获取它。
class JamesReentrantcy {
synchronized void doAll(){
doFirst();
doSecond();
}
synchronized void doFirst(){
System.out.println(“第一次操作成功。”);
}
synchronized void doSecond(){
System.out.println(“第二次操作成功。”);
}
}
等待/通知
wait/notify/notifyAll
方法在 Object
类中声明。wait
的作用可以使线程状态变成 WAITING
或 TIMED_WAITING
(如果已等待超时)状态。为了唤醒一个线程,可以执行以下任何操作:
-
另一个线程调用
notify
,唤醒在监视器上等待的任意线程。 -
另一个线程调用
notifyAll
,唤醒监视器上等待的所有线程。 -
如果调用
Thread#interrupt
。在这种情况下,会抛出InterruptedException
。
最常见的模式是条件循环:
class JamesConditionLoop {
private Boolean condition;
synchronized void waitForCondition()throws InterruptedException {
while(!condition){
wait();
}
}
synchronized void satisfCondition(){
condition = true ;
notifyAll();
}
}
最后
ActiveMQ消息中间件面试专题
- 什么是ActiveMQ?
- ActiveMQ服务器宕机怎么办?
- 丢消息怎么办?
- 持久化消息非常慢怎么办?
- 消息的不均匀消费怎么办?
- 死信队列怎么办?
- ActiveMQ中的消息重发时间间隔和重发次数吗?
ActiveMQ消息中间件面试专题解析拓展:
redis面试专题及答案
- 支持一致性哈希的客户端有哪些?
- Redis与其他key-value存储有什么不同?
- Redis的内存占用情况怎么样?
- 都有哪些办法可以降低Redis的内存使用情况呢?
- 查看Redis使用情况及状态信息用什么命令?
- Redis的内存用完了会发生什么?
- Redis是单线程的,如何提高多核CPU的利用率?
Spring面试专题及答案
- 谈谈你对 Spring 的理解
- Spring 有哪些优点?
- Spring 中的设计模式
- 怎样开启注解装配以及常用注解
- 简单介绍下 Spring bean 的生命周期
Spring面试答案解析拓展
高并发多线程面试专题
- 现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,并且 T3 线程在 T2 之后执行?
- Java 中新的 Lock 接口相对于同步代码块(synchronized block)有什么优势?如果让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。
- Java 中 wait 和 sleep 方法有什么区别?
- 如何在 Java 中实现一个阻塞队列?
- 如何在 Java 中编写代码解决生产者消费者问题?
- 写一段死锁代码。你在 Java 中如何解决死锁?
高并发多线程面试解析与拓展
jvm面试专题与解析
- JVM 由哪些部分组成?
- JVM 内存划分?
- Java 的内存模型?
- 引用的分类?
- GC什么时候开始?
JVM面试专题解析与拓展!
试专题解析与拓展!**
[外链图片转存中…(img-7xjBX6Wm-1715671867896)]