摘要:总结 每个对象有一个监视器锁(monitor)。下面两个方式,本质上都是通过监视器锁(monitor)来控制 同步代码块是通过 monitorenter 和 monitorexit 指令获取线程的执行权 同步方法通过加 ACC_SYNCHRONIZED 标识实现线程的执行权的控制 "同步代码块"的原
阅读全文
摘要:一、什么是死锁 线程死锁是指由于两个或者多个线程互相持有所需要的资源,导致这些线程一直处于等待其他线程释放资源的状态,无法前往执行,如果线程都不主动释放所占有的资源,将产生死锁。当线程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。 二、死锁的四个必要条件 互斥条件:线程要求对所分配的资源
阅读全文
摘要:总结 无锁 -> 偏向锁 -> 轻量级锁 (自旋锁) -> 重量级锁 (悲观锁) 锁状态对比: 偏向锁 轻量级锁 重量级锁 适用场景 只有一个线程进入同步块 虽然很多线程,但是没有冲突:多条线程进入同步块,但是线程进入时间错开因而并未争抢锁 发生了锁争抢的情况:多条线程进入同步块并争用锁 本质 取消
阅读全文
摘要:总结 线程的安全性问题体现在: 原子性:一个或者多个操作在 CPU 执行的过程中不被中断的特性 可见性:一个线程对共享变量的修改,另外一个线程能够立刻看到 有序性:程序执行的顺序按照代码的先后顺序执行 导致原因: 缓存导致的 --> 可见性问题 线程切换带来的 --> 原子性问题 编译优化带来的 -
阅读全文
摘要:总结 Java 为了让大家理解JMM(java memory model, java内存模型)中“内存可见性”的这个概念,提出了 happens-before 的概念。 如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须要存在 happens-before 关系 两个操作之间具有
阅读全文
摘要:总结 根据“任务的性质”分析 CPU 密集型任务 和内存打交道,大量计算。例如大数的计算,正则匹配 如何配置: CPU 密集型任务应配置尽可能小的线程,如配置 Ncpu+1 个线程的线程池(Ncpu 是处理器的核的数目),这样留一个空出来,用来做切换。。 如果线程太多,会造成线程在CPU内部的上下文
阅读全文
摘要:ForkJoin--分而治之策略 分而治之策略: 对于一个规模为 n 的问题,若该问题可以容易地解决(比如说 规模 n 较小)则直接解决,否则将其分解为 k 个规模较小的子问题,这些子问题 互相独立且与原问题形式相同(子问题相互之间有联系就会变为动态规范算法), 递归地解这些子问题,然后将各子问题的
阅读全文
摘要:区别 这两个方法来自不同的类分别是Thread (static sleep)和Object (wait) 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法(锁代码块和方法锁)。 wait,notify和notifyAll只能在同步控制方法或者同步控制块
阅读全文
摘要:线程常见函数 来源类 是否 Static 说明 是否释放锁 sleep() Thread static 只能操作当前线程。时间到后(没有interrupt的情况下),回到“就绪”状态 不 yield() Thread static 只能操作当前线程。只让出CPU时间片。不让出持有的锁和其他资源(磁盘
阅读全文
摘要:易错点1:锁一个可变对象 package cn.enjoyedu.ch1.syn; /** * 类说明:错误的加锁和原因分析 */ public class TestIntegerSyn { public static void main(String[] args) throws Interrup
阅读全文
摘要:总结 synchronized 和 ThreadLocal两个是相反的概念: Synchronized 保证数据的同步,因为它就是用于线程间的数据共享 ThreadLocal 不保证数据的同步,只保证线程间数据的隔离 synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问
阅读全文
摘要:对象锁 在 Java 中,每个对象都会有一个 monitor 对象,这个对象其实就是 Java 对象的锁,通常会被称为“内置锁”或“对象锁”。 类的对象可以有多个,所以每个对象有其独立的对象锁,互不干扰。 以下代码锁的均是对象锁: //对象锁,锁的是一个代码块 public void test(){
阅读全文
摘要:Java线程分为用户线程和守护线程。 守护线程是程序运行的时候在后台提供一种通用服务的线程。这意味着,当一个 Java 虚拟机中不存在非 Daemon 线程的时候, Java 虚拟机也会同时停掉所有守护线程,然后退出。 Java中把线程设置为守护线程的方法:在 start 线程之前调用线程的 set
阅读全文
摘要:线程状态转换图 新建(NEW):新建线程对象,未调用 start 方法可运行(RUNNABLE):线程对象创建后,被调用 start 方法。此状态的线程位于可运行线程池中,等待获取 CPU 的使用权运行中(RUNNING):线程获取了 CPU 的使用权,执行程序代码阻塞(BLOCKED):线程因为某
阅读全文
摘要:总结 java线程之间是协同式,不是抢占式 因为是协同式,所以线程之间都是“商量”着来,最佳实践是没有谁强迫谁终止的情况的,因此才会淘汰stop()方法,详见 多线程 - 为何要弃用stop() suspend()?(不过你硬要调用stop()就另当别论...) public void interr
阅读全文
摘要:不释放锁 线程执行同步代码块或同步方法时 程序调用Thread.sleep()、Thread.yield()方法暂停当前线程的执行,不释放锁; 线程执行同步代码块时,其它线程(线程B)调用该线程(线程A)suspend()方法将该线程(线程A)挂起,该线程(线程A)不会释放锁(同步监视器) 尽量避免
阅读全文
摘要:stop弃用 stop()会释放所有的锁 stop()天生不安全,因为它会强制终止未结束的方法(包括run方法),不管run方法是否执行完了,并且还会释放这个线程所持有的所有的锁对象这会导致对象处于不一致状态。 例:从一个账户向另一个账户转账的过程中被终止,钱已经转出,但没有输入目标账户。 当线程要
阅读全文
摘要:1.Thread.start和Thread.run是什么? start()方法 线程类的start()方法可以用来启动线程;该方法会在内部调用Runnable接口的run()方法,以在单独的线程中执行run()方法中指定的代码。 start()方法启动线程执行以下任务: 它创建了一个新线程 线程从N
阅读全文
摘要:通过Executor 的工具类,创建三种类型的普通线程池: https://blog.csdn.net/weixin_41891854/article/details/81265772 Executors 创造线程的缺点 https://blog.csdn.net/qq_31615049/artic
阅读全文
摘要:总结 并行(parallelism),是同一时刻,两个线程都在执行。 并发(concurrency),是同一时刻,只有一个执行,但是一个时间段内,两个/多个线程都执行了。 并行 并发
阅读全文