揭阳东莞网站建设,wordpress微信qq登录,深圳比较好的公司,无广告自助建站目录
1 synchronized 的特性
1#xff09;互斥
2) 刷新内存#xff08;内存可见性#xff09;
3) 可重入
2 synchronized 使用示例 1) 直接修饰普通方法:
2) 修饰静态方法:
3) 修饰代码块:
.3 Java 标准库中的线程安全类 1 synchronized 的特性
1#x…目录
1 synchronized 的特性
1互斥
2) 刷新内存内存可见性
3) 可重入
2 synchronized 使用示例 1) 直接修饰普通方法:
2) 修饰静态方法:
3) 修饰代码块:
.3 Java 标准库中的线程安全类 1 synchronized 的特性
1互斥 synchronized 会起到互斥效果, 某个线程执行到某个对象的 synchronized 中时, 其他线程如果也执行到 同一个对象 synchronized 就会阻塞等待. 进入 synchronized 修饰的代码块, 相当于 加锁 退出 synchronized 修饰的代码块, 相当于 解锁 synchronized用的锁是存在Java对象头里的。 synchronized的底层是使用操作系统的mutex lock实现的. 理解 阻塞等待. 针对每一把锁, 操作系统内部都维护了一个等待队列. 当这个锁被某个线程占有的时候, 其他线程尝试进行加锁, 就加不上了, 就会阻塞等待, 一直等到之前的线程解锁之后, 由操作系统唤醒一个新的线程, 再来获取到这个锁. 注意 : 上一个线程解锁之后, 下一个线程并不是立即就能获取到锁. 而是要靠操作系统来 唤醒. 这也就是操作系统线程调度的一部分工作. 假设有 A B C 三个线程, 线程 A 先获取到锁, 然后 B 尝试获取锁, 然后 C 再尝试获取锁, 此时 B 和 C 都在阻塞队列中排队等待. 但是当 A 释放锁之后, 虽然 B 比 C 先来的, 但是 B 不一定就能 获取到锁, 而是和 C 重新竞争, 并不遵守先来后到的规则. 2) 刷新内存内存可见性 synchronized 的工作过程: 获得互斥锁 从主内存拷贝变量的最新副本到工作的内存 执行代码 将更改后的共享变量的值刷新到主内存 释放互斥锁 所以 synchronized 也能保证内存可见性. 与 volatile相似。
3) 可重入
synchronized 同步块对同一条线程来说是可重入的不会出现自己把自己锁死的问题 代码示例 在下面的代码中 increase 和 increase2 两个方法都加了 synchronized, 此处的 synchronized 都是针对 this 当前 对象加锁的. 在调用 increase2 的时候, 先加了一次锁, 执行到 increase 的时候, 又加了一次锁. (上个锁还没释放, 相当于连续加两次锁) //一针对this对象
static class Counter {public int count 0;synchronized void increase() {count;}synchronized void increase2() {increase();}
}
//二针对lockerprivate static Object locker new Object();Thread t1 new Thread(() - {synchronized (locker1) {// 此处的 sleep 很重要. 要确保 t1 和 t2 都分别拿到一把锁之后, 再进行后续动作.synchronized (locker1) {System.out.println(t1 加锁成功!);}}}); 这个代码是完全没问题的. 因为 synchronized 是可重入锁. 在可重入锁的内部, 包含了 线程持有者 和 计数器 两个信息. 如果某个线程加锁的时候, 发现锁已经被人占用, 但是恰好占用的正是自己, 那么仍然可以继续获取 到锁, 并让计数器自增. 解锁的时候计数器递减为 0 的时候, 才真正释放锁. (才能被别的线程获取到 2 synchronized 使用示例 synchronized 本质上要修改指定对象的 对象头. 从使用角度来看, synchronized 也势必要搭配一个具体的对象来使用. 1) 直接修饰普通方法: 锁的 SynchronizedDemo 对象 public class SynchronizedDemo { public synchronized void methond() { } } 2) 修饰静态方法: 锁的 SynchronizedDemo 类的对象 public class SynchronizedDemo { public synchronized static void method() { } } 3) 修饰代码块:
明确指定锁当前哪个对象 //1. 锁当前this对象 public class SynchronizedDemo { public void method() { synchronized (this) { } } } //2.锁类对象 public class SynchronizedDemo { public void method() { synchronized (SynchronizedDemo.class) { } } } 两个线程竞争同一把锁, 才会产生阻塞等待. .3 Java 标准库中的线程安全类 这些是线程安全的. 使用了一些锁机制来控制. Vector (不推荐使用)HashTable (不推荐使用)ConcurrentHashMapStringBuffer 核心方法都带有 synchronized . 结语synchronized的相关分享到这里就结束了希望对大家的学习会有帮助如果大家有什么问题或者不同的见解欢迎大家评论区的留言 感谢支持