java线程学习
光明的心2
这个作者很懒,什么都没留下…
展开
-
自定义线程池
线程池 1.自定义线程池 自定义拒绝策略接口 @FunctionalInterface public interface RejectPolicy<T> { /** * 自定义拒绝策略方法 * * @param queue 阻塞队列 * @param task 线程任务 */ void reject(BlockingQueue<T> queue, T task); } 自定义任务队列 public class原创 2021-01-15 17:33:12 · 185 阅读 · 0 评论 -
Volatile 原理
Volatile 原理 volatile 的底层实现原理是内存屏障,Memory Barrier 对 volatile 变量的写指令后会加入 写屏障 对 volatile 变量的读指令前会加入 读屏障 1. 如何保证可见性 写屏障保证在该屏障之前的,对共享变量的改动,都同步到主存当中 public void actor2() { num = 2; // volatile 变量 ready = true; // 写屏障 } 而读屏障保证在该屏障之后,对共享变量的读取,加载的是主存中最新数据原创 2020-12-15 19:19:30 · 212 阅读 · 0 评论 -
java 内存模型
java 内存模型 JMM 即 Java Memory Model,它定义了主存、工作内存抽象概念。 JMM 体现在以下几个方面 原子性 - 保证指令不会受到线程上下文切换的影响 可见性 - 保证指令不会受 cpu 缓存的影响 有序性 - 保证指令不会受 cpu 指令并行优化的影响 可见性 main 线程对 run 变量的修改对于 t 线程不可见,导致了 t 线程无法停止: private static boolean run = true; public static void main(S原创 2020-11-28 17:14:40 · 161 阅读 · 0 评论 -
条件变量
条件变量 synchronized 中也有条件变量,就是等待队列 waitSet,当条件不满足时进入 waitSet 等待 ReentrantLock 的条件变量比 synchronized 强大之处在于,它是支持多个条件变量的。 使用要点: await 前需要获得锁 await 执行后,会释放锁,进入 conditionObject 等待 await 的线程被唤醒(或打断、或超时)重新竞争 lock 锁 竞争 lock 锁成功后,从 await 后继续执行 private static Reentr原创 2020-11-21 19:53:12 · 142 阅读 · 0 评论 -
ReentrantLock
ReentrantLock 相对于 synchronized 它具备如下特点 可中断 可以设置超时时间 可以设置为公平锁 支持多个条件变量 与 synchronized 一样,都支持可重入 基本语法 // 获取锁 reentrantLock.lock(); try { // 临界区 }finally { // 释放锁 reentrantLock.unlock(); } 可重入 可重入是指同一个线程如果首次获得了这把锁,如果是可重入的锁,有权利再次获取这把锁,如果是不可原创 2020-11-19 20:47:08 · 106 阅读 · 0 评论 -
sleep(long n) 和 wait(long n) 的区别
sleep(long n) 和 wait(long n) 的区别 sleep 是 Thread 方法,而 wait 是 Object 的方法 sleep 不需要强制和 synchronized 配合使用,但 wait 需要 和 synchronized 一起用 sleep 在睡眠的同时,不会释放对象锁的,但 wait 在等待的时候会释放对象锁 park unpark 与 wait notify wait, notify 和 notifyAll 必须配合 Object Monitor 一起使用,而 pa原创 2020-11-14 17:09:37 · 443 阅读 · 0 评论 -
wait notify 原理
wait notify 原理 Owner 线程(获取锁的线程)发现条件不满足,调用 wait 方法,即可进入 WaitSet 变为 WAITING 状态 BLOCKED 和 WAITING 的线程都处于 阻塞状态,不占用 CPU 时间片 BLOCKED 线程会在Owner 线程释放锁时唤醒 WAITING 线程会在 Owner 线程调用 notify 或 notifyAll 时唤醒,但唤醒后并不意味着立刻获得锁,仍需进入 EntryList 重新竞争 join 原理 是调用者轮询检查线程 alive原创 2020-11-03 09:58:28 · 274 阅读 · 0 评论 -
锁膨胀
锁膨胀 如果在尝试加轻量级锁的过程中,CAS 操作无法成功,这时一种情况就是有其它线程为此对象加上了轻量级锁(有竞争),这时需要进行锁膨胀,将轻量级锁变为重量级锁。 static Object obj = new Object(); public static void method1() { synchronized( obj ) { // 同步块 } } 当 Thread-1 进行轻量级加锁时,Thread-0 已经对该对象加了轻量级锁 这时 Thread-1原创 2020-10-24 10:16:06 · 211 阅读 · 1 评论 -
synchronized 原理
**synchronized 原理 ** static final Object lock = new Object(); static int counter = 0; public static void main(String[] args) { synchronized(lock) { counter++; } } 对应的字节码为 public static void main(java.lang.String[]); descriptor: ([Ljava/原创 2020-10-07 16:00:31 · 103 阅读 · 0 评论 -
Monitor概念
Monitor概念 Monitor 被翻译为监视器或管程 每个 Java 对象都可以关联一个 Monitor 对象, 如果使用 synchronized 给对象上锁(重量级)之后,该对象头的 Mark Word 中就被设置指向 Monitor 对象的指针 Monitor 结构如下 刚开始 Monitor 中 Owner 为 null 当 Thread-0 执行 synchronized(object) 上锁就会将 Monitor 的所有者 Owner 置为 Thread-0, 同时对象 object 中原创 2020-10-06 14:24:10 · 2776 阅读 · 1 评论 -
Java线程学习 (六)
**方法上的 synchronized ** class Test { public synchronized void test() { } } // 等价于 class Test { public void test() { synchronized(this) { } } } class Test { public synchronized static void test() {原创 2020-09-23 10:35:01 · 77 阅读 · 0 评论 -
终止模式之两阶段终止模式
终止模式之两阶段终止模式 在一个线程 T1 中如何 “优雅” 终止线程 T2 ? 1. 利用 isInterrupted class TwoPhaseTermination { private Thread monitor; public void start(){ monitor = new Thread(() -> { while (true){ Thread current = Thread.curren原创 2020-09-16 19:01:28 · 259 阅读 · 0 评论 -
java 线程学习(五)
Java 多线程指令交错 两个线程对初始值为 0 的静态变量一个做自增,一个做自减,各做 5000 次,结果有可能不为0 private static int count = 0; public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(() -> { for (int i = 0; i < 5000; i++) {原创 2020-09-14 20:04:02 · 199 阅读 · 0 评论 -
java 线程学习 (四)
主线程与守护线程 默认情况下,Java 进程需要等待所有线程都运行结束,才会结束。有一种特殊的线程叫做守护线程,只要其他非守护线程运行结束了,即使守护线程的代码没有执行完,也会强制结束。 例: public static void main(String[] args) throws InterruptedException { System.out.println("开始运行"); Thread t1 = new Thread(() -> {原创 2020-09-07 20:48:08 · 139 阅读 · 0 评论 -
Java 线程学习 (三)
join 方法详解 static int r = 0; public static void main(String[] args) throws InterruptedException { test(); } private static void test() throws InterruptedException { System.out.println("开始"); Thread t1 = new Thread( ()原创 2020-09-04 11:21:22 · 78 阅读 · 0 评论 -
java 线程学习(二)
线程上下文切换(Thread Context Switch) 因为以下一些原因导致cpu不再执行当前的线程,转而执行另一个线程的代码 线程的cpu时间片用完 垃圾回收 有更高优先级的线程需要运行 线程自己调用了sleep、yield、wait、join、park、synchronized、lock等方法 当 Context Switch 发生时,需要由操作系统保存当前线程的状态,并恢复另一个线程的状态,Java中对应的概念就是程序计数器,它的作用是记住下一条jvm指令的执行地址,是线程私有的 状态包括原创 2020-08-09 11:39:38 · 81 阅读 · 0 评论 -
java线程学习笔记
java线程运行基本原理 Java Virtual Machine Stacks (Java 虚拟机栈) JVM中由堆、栈、方法区所组成,其中栈内存就是给线程使用,每个线程启动后,虚拟机就会为其分配一块栈内存。 每个栈由多个栈帧(Frame)组成,对应着每次方法调用时所占用的内存 每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法 public class TestFrame { public static void main(String[] args) { method原创 2020-08-08 17:24:23 · 94 阅读 · 0 评论