当前位置: 首页 > news >正文

用虚拟主机做网站wordpress多城市子站

用虚拟主机做网站,wordpress多城市子站,阳江市建设网站,网站建设费用的会计1.Synchornized对象锁一般我们要解决临界区中的静态条件发生,我们一般使用两种手段阻塞式解决方案:synchronized lock非阻塞式解决方案: 原子类下面我们着重讲解阻塞式解决方案:synchornizedsynchronized俗称对象锁,采用互斥的方…

1.Synchornized对象锁

一般我们要解决临界区中的静态条件发生,我们一般使用两种手段

  1. 阻塞式解决方案:synchronized lock
  2. 非阻塞式解决方案:  原子类

下面我们着重讲解阻塞式解决方案:synchornized

synchronized俗称对象锁,采用互斥的方案让同一时刻至多只有一个线程能持有对象锁,其他线程想要获取这个对象锁就会被阻塞住,这样就保证拥有锁的线程可以安全执行临界区内的代码,不用担心线程上下文切换导致的并发问题

synchronized(对象){//线程1执行,线程2阻塞//临界区}

synchronized(对象)中的对象,可以想象成一个房间(room),有唯一的入口(房门),房间只能一次进入一个人,而我们的线程t1和线程t2就是两个人

当线程1执行到synchronized(room)时就好比t1进入了房间,锁住了门拿走了钥匙,在门内执行临界区代码

如果t2也走到了synchronized时,会发现门被锁住了,就会在门外等待(阻塞),这中间即使t1的cpu时间片不幸被用完,被提出了门外,但是由于钥匙还在它身上,因此t2还是进不来,必须等到t1来执行完代码然后把锁打开放出钥匙才能执行。

语法:

class Test{public synchornized void test(){}
}
//等价于
class Test{public void test(){sychronized(this){} }
}
class Test{public synchornized statsic void test(){}
}
//等价于
class Test{public static void test(){sychronized(Test.class){}}}

sychornized底层

Monitor对象头

其中的状态会根据锁的升级而改变

Monitor工作原理

当一个线程进入到sychronized中时,Monitor内部会发生改变,如果发现Monitor中的Owner指向了别的线程,就会进入EntryList阻塞队列进行等待。当线程执行完了以后,WaitSet就会指向这个线程,然后Thread就会让出锁,Owner就会指向其他阻塞队列中的线程

如何判断是否获取锁:由Monitor中的Owner来判定,如果Owner指向的线程为进来的线程就说明拥有这把锁.

Sychornized优化

1.轻量级锁

如果一个对象虽然有多个线程访问,但是访问的时间是错开的,也就是没有竞争,那么可以使用轻量级锁来优化

轻量级锁对使用者是透明的,既语法仍然是synchronized

假设有两个方法同步块,利用同一个对象加锁

static final Object obj = new Object();
public static void method1(){synchronized(obj){//同步块Amethod2()}}public static void method2(){synchronized(obj){//同步块B}}

此时由于一个锁有两个线程获取锁,但是没有发生竞争,因为第二个方法里的锁以及在方法1中获取了,所以此时的锁会升级为轻量级锁

2.锁膨胀

如果在尝试加轻量级锁的过程中,CAS操作无法成功,这时一种情况就是有其他线程为此对象加上了轻量级锁(有竞争),这时需要进行锁膨胀,将轻量级锁升级为重量级锁

static Object obj = new Object();
public static void method1(){synchronized(obj){//同步块}}

当Thread-1进行轻量级加锁时,Thread-0以及对该对象加了轻量级锁

这时Thread1加轻量级锁失败,进入锁膨胀流程

  • 即为Object对象申请Monitor锁,让Object指向重量级锁地址
  • 然后自己进入Monitor的EntryList BLOCKED

当Thread0退出同步块解锁时,使用CAS将Mark Word的值恢复给对象头,失败。这时就会进入重量级锁流程,即按照Monitor地址找到Monitor对象,设置Owner为null,唤醒EntryList中BLOCKED线程

自旋优化

偏向锁

只有第一次使用CAS将线程ID设置到对象的Mark Word头,之后发现这个线程ID是自己的就表示没有竞争,不用重新CAS,以后只要不发生竞争,这个对象就归改线程所有

重量级锁

重量级锁是 synchronized 在处理激烈线程竞争时使用的同步机制。它依赖于操作系统的互斥量(mutex) 实现,线程的阻塞与唤醒需要通过操作系统内核态的介入,因此开销较大,故称为 “重量级”。

当多个线程频繁竞争同一把锁,且轻量级锁的自旋优化(见下文)无法解决竞争时,锁会膨胀为重量级锁,此时线程会进入阻塞状态,放弃 CPU 资源,等待被唤醒后重新竞争锁。

优点
  • 能稳定处理激烈竞争场景,确保多线程同步的正确性(原子性、可见性、有序性)。
缺点
  • 性能开销大:线程的阻塞与唤醒需要从用户态切换到内核态(上下文切换),而内核态操作的耗时远高于用户态(通常是微秒级 vs 纳秒级)。
  • 效率低:阻塞的线程无法参与 CPU 调度,可能导致资源利用率下降。

2.ReentrantLock可重入锁

ReentrantLock相对于synchronized有如下特点

  • 可中断
  • 可以设置超时时间
  • 可以设置为公平锁(先进先出)
  • 支持多个条件变量(可以对变量细分,如notify可以细分唤醒变量,而synchronized就是直接全部唤醒)

与synchronized一样,都支持可重入

基本语法

和synchronized不一样,reentrantlock是对象而非方法,在使用前需要先new一个

//获取锁
reentrantlock.lock();
try{//临界区} finally{//释放锁reentrantlock.unlock();    }

可重入

如下图,我们两个方法都用Reentrantlock加锁,这样它们每次获取都是获取的同一把锁,相当于重入了同一把锁

public void outerMethod() {lock.lock();try {System.out.println("获取外层锁");innerMethod(); // 调用内层方法} finally {lock.unlock();System.out.println("释放外层锁");}}public void innerMethod() {lock.lock();try {System.out.println("获取内层锁");System.out.println("当前锁的持有次数: " + lock.getHoldCount());} finally {lock.unlock();System.out.println("释放内层锁");}}

可打断

当一个线程正在等待获取锁时,可以被其他线程通过interrupt()方法中断,从而避免无限等待。这是ReentrantLock相比synchronized的一个重要优势,后者在等待锁时无法被中断。

ReentrantLock提供了两种获取锁的方式:

  1. 不可打断模式:使用lock()方法获取锁。若锁被其他线程持有,当前线程会进入阻塞状态,且无法被中断,直到锁被释放。
  2. 可打断模式:使用lockInterruptibly()方法获取锁。若锁被其他线程持有,当前线程会进入阻塞状态,但可以被其他线程中断(通过调用Thread.interrupt())。

如下代码所示:

// 线程1:持有锁并休眠5秒Thread t1 = new Thread(() -> {lock.lock();try {System.out.println("线程1获取锁,开始执行...");Thread.sleep(5000); // 模拟长时间持有锁} catch (InterruptedException e) {System.out.println("线程1被中断");} finally {lock.unlock();System.out.println("线程1释放锁");}});// 线程2:使用lockInterruptibly()获取锁Thread t2 = new Thread(() -> {try {System.out.println("线程2尝试获取锁(可打断模式)");lock.lockInterruptibly();try {System.out.println("线程2获取锁,开始执行");} finally {lock.unlock();System.out.println("线程2释放锁");}} catch (InterruptedException e) {System.out.println("线程2被中断,放弃获取锁");Thread.currentThread().interrupt(); // 恢复中断状态}});

公平锁与非公平锁(Fairness)

  • 公平锁:线程按照请求锁的顺序获取锁(FIFO),避免 “线程饥饿”。
  • 非公平锁:允许插队,锁释放时任何线程都可能竞争获取锁,性能更高

创建方式

ReentrantLock fairLock = new ReentrantLock(true);  // 公平锁
ReentrantLock unfairLock = new ReentrantLock(false); // 非公平锁(默认)
  • 公平锁:适用于需要保证线程执行顺序的场景(如资源分配)。
  • 非公平锁:适用于高并发场景,减少线程切换开销。

 条件变量(Condition)

提供更灵活的线程等待 / 通知机制,替代synchronizedwait()/notify()

使用方式

  • lock.newCondition():创建与锁绑定的条件变量。
  • condition.await():线程等待,释放锁。
  • condition.signal()/signalAll():唤醒等待的线程
ReentrantLock lock = new ReentrantLock();
Condition notFull = lock.newCondition();
Condition notEmpty = lock.newCondition();// 生产者线程
lock.lock();
try {while (queue.isFull()) {notFull.await(); // 队列满,等待}queue.add(item);notEmpty.signal(); // 通知消费者
} finally {lock.unlock();
}// 消费者线程
lock.lock();
try {while (queue.isEmpty()) {notEmpty.await(); // 队列空,等待}queue.take();notFull.signal(); // 通知生产者
} finally {lock.unlock();
}

Volatile

Volatile原理

volatile的底层实现原理是内存屏障,Memory Barrier

  • 对volatile变量的写指令后会加入写屏障
  • 对volatile变量的读指令前会加入读屏障

Java 内存模型规定了线程之间的变量访问规则:

  • 主内存:所有变量的原始值存储在此。
  • 工作内存:每个线程有自己的工作内存,保存了从主内存拷贝的变量副本。

可见性问题:当线程 A 修改了变量 X 的值,可能只更新了自己的工作内存,而未及时同步到主内存;此时线程 B 读取变量 X 时,仍使用自己工作内存中的旧值。

写屏障保证在该屏障之前的,对共享变量的改动,都同步到主存当中

public class VolatileExample {private volatile boolean flag = false;public void writer() {flag = true; // 写屏障:确保flag=true立即刷新到主内存}public void reader() {while (!flag) { // 读屏障:确保每次读取flag时都从主内存获取// 循环等待}System.out.println("flag is now true");}
}

读写屏障如何保证有序性

编译器和处理器为了优化性能,可能会对指令进行重排序。但volatile变量的读写操作不会被重排序:

  • 写操作前的指令不会被重排序到写操作之后。
  • 读操作后的指令不会被重排序到读操作之前。
int a = 0;
volatile boolean flag = false;public void init() {a = 1;         // 1flag = true;   // 2(写操作禁止重排序到1之前)
}public void use() {if (flag) {    // 3(读操作禁止重排序到4之后)int b = a; // 4}
}

http://www.dtcms.com/a/415575.html

相关文章:

  • Java 黑马程序员学习笔记(进阶篇14)
  • 网站开发的理解制作网站软件网站
  • 长沙网页网站制作网站建设常用的工具
  • 上海装修网站建设深圳安全教育平台
  • 房子装修报价清单表湖北seo网站多少钱
  • 列举网站开发常用的工具免费软件有哪些
  • jsp网站开发环境配置直播网站开发需要多少钱
  • Ingress:轻松拿捏集群流量管理
  • 网站正在建设中...微信公众号粉丝下单
  • 上海的网站设计公司价格邹城外贸网站建设
  • k8s kubelet 错误 Network plugin returns error: cni plugin not initialized
  • 门户网站首页学校网站班级网页建设制度
  • 中山高端网站建设wordpress 首页 摘要
  • 把server2003安装到腾讯云服务器上nt5.2.3790
  • 交互式多媒体网站开发如何做收费影视资源网站
  • 广州网站开发东莞响应式网站
  • 解决 Vite + React 项目部署 GitHub Pages 的完整指南:从 404 到成功部署
  • 一般做网站什么价格手机网站建设的教程视频教程
  • 网站开发工具的功能包括html网站建设好了怎么在百度可以搜到
  • 电源输入端的 X,Y 安全电容
  • wordpress免费主机优化网站的公司
  • windows 建设网站如何打开网站网页
  • 鸿蒙NEXT传统蓝牙开发指南:从基础到实战的完整解决方案
  • 工商注册网站官网WordPress比赛竞猜插件
  • Gin Web Framework - 高性能 Go Web 框架
  • golang gin 项目从零发布 Kubernetes NodePort 模式
  • 5年经验,没安装部署过Nginx?
  • Java面试-并发面试(二)
  • 纺织网站制作123纺织网科技小制作小发明
  • HashMap底层源码