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

本地wordpress怎么弄网站网站建设 今网科技

本地wordpress怎么弄网站,网站建设 今网科技,dw制作网页的过程,没有网站如何做淘宝客Java 中的 synchronized 和 Lock:如何保证线程安全 引言 在 Java 多线程编程中,线程安全是一个核心问题。当多个线程同时访问共享资源时,可能会导致数据不一致或其他不可预期的结果。synchronized关键字和Lock接口是 Java 中实现线程同步的…

Java 中的 synchronized 和 Lock:如何保证线程安全

引言

在 Java 多线程编程中,线程安全是一个核心问题。当多个线程同时访问共享资源时,可能会导致数据不一致或其他不可预期的结果。synchronized关键字和Lock接口是 Java 中实现线程同步的两种主要方式,本文将深入探讨它们的工作原理、使用场景及源码实现,并通过代码样例解析其线程安全机制。

一、线程安全基础概念

1.1 什么是线程安全?

线程安全是指当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为。

1.2 线程安全问题的根源

  • 原子性:一个或多个操作在 CPU 执行过程中被中断
  • 可见性:一个线程修改了共享变量的值,其他线程未能及时看到最新的值
  • 有序性:程序执行的顺序可能与代码顺序不一致(指令重排序)

1.3 Java 内存模型(JMM)

Java 内存模型规定了线程之间的可见性和有序性,其核心概念包括:

  • 主内存:所有变量存储的区域
  • 工作内存:每个线程独立拥有的内存区域,存储线程使用的变量副本
  • 内存屏障:保证特定操作的执行顺序和可见性

二、synchronized 关键字

2.1 synchronized 的基本用法

synchronized关键字可以修饰方法或代码块,确保同一时刻只有一个线程可以执行该代码:

public class SynchronizedExample {private int count = 0;// 同步方法public synchronized void increment() {count++;}// 同步代码块public void decrement() {synchronized (this) {count--;}}// 静态同步方法public static synchronized void staticMethod() {// ...}
}

2.2 synchronized 的底层实现

2.2.1 对象头与 Monitor

在 Java 中,每个对象都有一个对象头(Object Header),其中包含了 Mark Word。当对象被synchronized修饰时,Mark Word 会存储指向 Monitor 对象的指针。

Monitor 是 Java 中实现同步的基础,它是一个对象级的同步机制,本质上是一个锁的实现。每个 Java 对象都可以关联一个 Monitor,当一个线程尝试访问被synchronized修饰的代码块时,它必须先获得该对象的 Monitor。

2.2.2 字节码层面的实现

通过javap -v命令查看编译后的字节码,可以看到synchronized代码块使用monitorentermonitorexit指令实现:

public void decrement();descriptor: ()Vflags: ACC_PUBLICCode:stack=2, locals=3, args_size=10: aload_01: dup2: astore_13: monitorenter            // 进入同步块4: aload_05: dup6: getfield      #2        // Field count:I9: iconst_110: isub11: putfield      #2       // Field count:I14: aload_115: monitorexit           // 正常退出同步块16: goto          2419: astore_220: aload_121: monitorexit           // 异常退出同步块22: aload_223: athrow24: return
2.2.3 重量级锁与轻量级锁

在 JDK 1.6 之前,synchronized 是一个重量级锁,性能较低。JDK 1.6 引入了锁升级机制,优化了 synchronized 的性能:

  • 无锁状态:对象头 Mark Word 存储对象的哈希码等信息
  • 偏向锁:单线程环境下,锁偏向第一个获得它的线程
  • 轻量级锁:多线程环境下,线程交替执行同步块,通过 CAS 操作获取锁
  • 重量级锁:多个线程同时竞争锁,向操作系统申请互斥量

2.3 synchronized 的特性

  • 可重入性:同一个线程可以多次获取同一把锁
  • 不可中断性:一旦线程获取锁,其他线程只能等待锁释放
  • 保证原子性、可见性和有序性

三、Lock 接口与 ReentrantLock

3.1 Lock 接口的基本方法

public interface Lock {void lock();                          // 获取锁void lockInterruptibly() throws InterruptedException; // 可中断获取锁boolean tryLock();                    // 尝试非阻塞获取锁boolean tryLock(long time, TimeUnit unit) throws InterruptedException; // 超时获取锁void unlock();                        // 释放锁Condition newCondition();             // 获取等待通知组件
}

3.2 ReentrantLock 的使用示例

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class LockExample {private final Lock lock = new ReentrantLock();private int count = 0;public void increment() {lock.lock();try {count++;} finally {lock.unlock();}}public void decrement() {lock.lock();try {count--;} finally {lock.unlock();}}
}

3.3 ReentrantLock 的源码解析

3.3.1 AQS(AbstractQueuedSynchronizer)

ReentrantLock 的核心是基于 AQS(AbstractQueuedSynchronizer)实现的。AQS 是一个用于构建锁和同步器的框架,它使用一个整型的 state 变量来表示锁的状态,并维护一个 FIFO 队列来管理等待线程。

public class ReentrantLock implements Lock, java.io.Serializable {private final Sync sync;abstract static class Sync extends AbstractQueuedSynchronizer {// ...}static final class NonfairSync extends Sync {// 非公平锁实现}static final class FairSync extends Sync {// 公平锁实现}
}
3.3.2 公平锁与非公平锁

ReentrantLock 支持公平锁和非公平锁两种模式:

  • 公平锁:按照线程请求锁的顺序获取锁
  • 非公平锁:线程可以抢占式获取锁,不考虑请求顺序
// 创建公平锁
Lock fairLock = new ReentrantLock(true);// 创建非公平锁(默认)
Lock nonfairLock = new ReentrantLock();
3.3.3 锁的获取与释放

以非公平锁为例,lock () 方法的实现:

final void lock() {if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());elseacquire(1);
}public final void acquire(int arg) {if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt();
}protected final boolean tryAcquire(int acquires) {return nonfairTryAcquire(acquires);
}final boolean nonfairTryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}else if (current == getExclusiveOwnerThread()) {int nextc = c + acquires;if (nextc < 0) // overflowthrow new Error("Maximum lock count exceeded");setState(nextc);return true;}return false;
}
3.3.4 可重入性实现

ReentrantLock 的可重入性通过 state 变量实现:当同一个线程再次获取锁时,state 值递增;释放锁时,state 值递减。当 state 值为 0 时,表示锁已完全释放。

protected final boolean tryRelease(int releases) {int c = getState() - releases;if (Thread.currentThread() != getExclusiveOwnerThread())throw new IllegalMonitorStateException();boolean free = false;if (c == 0) {free = true;setExclusiveOwnerThread(null);}setState(c);return free;
}

四、synchronized 与 Lock 的对比

特性synchronizedLock
语法内置语言关键字接口,需要显式调用 lock () 和 unlock ()
锁的获取自动获取和释放手动获取和释放,必须在 finally 中释放
可中断性不可中断可中断(lockInterruptibly ())
公平性非公平可选择公平或非公平
锁的状态无法判断可以判断(isLocked ())
条件变量单一条件变量可以创建多个条件变量
性能JDK 1.6 后优化,轻量级锁性能接近 Lock高并发场景下性能更优

五、线程安全实践:银行账户示例

5.1 使用 synchronized 实现

public class BankAccount {private double balance;public BankAccount(double balance) {this.balance = balance;}// 同步方法实现线程安全public synchronized void deposit(double amount) {balance += amount;}// 同步方法实现线程安全public synchronized void withdraw(double amount) {if (balance >= amount) {balance -= amount;} else {throw new IllegalArgumentException("余额不足");}}public synchronized double getBalance() {return balance;}
}

5.2 使用 ReentrantLock 实现

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class BankAccount {private double balance;private final Lock lock = new ReentrantLock();public BankAccount(double balance) {this.balance = balance;}public void deposit(double amount) {lock.lock();try {balance += amount;} finally {lock.unlock();}}public void withdraw(double amount) {lock.lock();try {if (balance >= amount) {balance -= amount;} else {throw new IllegalArgumentException("余额不足");}} finally {lock.unlock();}}public double getBalance() {lock.lock();try {return balance;} finally {lock.unlock();}}
}

六、总结

6.1 synchronized 的适用场景

  • 简单的同步需求
  • 不需要锁的高级特性(可中断、公平性等)
  • 代码简洁性要求高

6.2 Lock 的适用场景

  • 需要可中断锁
  • 需要公平锁
  • 需要多个条件变量
  • 在高并发场景下追求更好的性能

6.3 最佳实践

  1. 优先使用 synchronized,因为它更简洁,且 JDK 1.6 后性能已经得到优化
  2. 在需要高级特性时使用 Lock
  3. 使用 Lock 时,必须在 finally 块中释放锁
  4. 避免锁的嵌套,防止死锁
  5. 对性能敏感的场景,考虑使用细粒度的锁

通过synchronizedLock,Java 提供了强大而灵活的线程同步机制,开发者可以根据具体场景选择合适的同步方式,确保多线程程序的安全性和性能。


文章转载自:

http://eGMCjLwA.zrfwz.cn
http://Euc2YVdE.zrfwz.cn
http://pvTGpWhI.zrfwz.cn
http://C9vgnBZJ.zrfwz.cn
http://rv8X3Kks.zrfwz.cn
http://jF9hll4n.zrfwz.cn
http://w7vNaJg1.zrfwz.cn
http://BY3jv6cF.zrfwz.cn
http://1uWVP3MZ.zrfwz.cn
http://U0h7M350.zrfwz.cn
http://pMbz4eWH.zrfwz.cn
http://Q6Z1eZ58.zrfwz.cn
http://8t3EKNJz.zrfwz.cn
http://0HzLWS3P.zrfwz.cn
http://MNpF9tED.zrfwz.cn
http://dOtZQFap.zrfwz.cn
http://ypfpm6lG.zrfwz.cn
http://Wd5ZBMzG.zrfwz.cn
http://ZmR9ra5h.zrfwz.cn
http://DtVtyvrl.zrfwz.cn
http://5VXTflW5.zrfwz.cn
http://QLSMAGOn.zrfwz.cn
http://cnjWQahb.zrfwz.cn
http://9tWf67ry.zrfwz.cn
http://iZ6MvC20.zrfwz.cn
http://4nSz7Uae.zrfwz.cn
http://C72jViu7.zrfwz.cn
http://Ev5xuiRN.zrfwz.cn
http://1gi74EQW.zrfwz.cn
http://05cQvLid.zrfwz.cn
http://www.dtcms.com/wzjs/629287.html

相关文章:

  • 免费app制作网站杭州公司注册多少钱
  • 整站下载器 安卓版龙岩天宫山缆车开放时间
  • 做游戏直播那个网站好北京网站空间
  • 分析竞争对手的网站警惕网站免费看手机
  • 中国做铁塔的公司网站网络平台营销
  • 单页网站有哪些做oa好 还是做网站好
  • 韩国网站 后缀深圳网页设计兴田德润电话多少
  • 太原网站建设服务哪个网站可以做图交易平台
  • 网站设计公司 上商城开发价格服务
  • 做海报网站找网站开发项目
  • 西安企业网站建设价格陕西恒立建设集团网站
  • 怎样开发网站建设网站建设费用申报
  • 对接空间站梧州网站推广
  • 网站源码分享网郑州量站站软件开发有限公司
  • asp网站ftp入侵高度重视机关门户网站建设
  • 网站建设 淘宝详情住房和城乡建设部网站施工员证
  • 宿迁网站建设怎么收费宁波市网站集约化建设通知
  • 网站建设指导方案开什么网店简单又挣钱
  • 互联网公司排名前十的在哪些城市官网seo哪家公司好
  • 做家政网站公司名称甘肃省建设厅门户网站
  • 网站被k了怎么办免费商城系统网站建设
  • 定制开发电商网站建设多少钱阿里巴巴运营教程
  • 如何建设电影会员网站html5网站制作软件
  • 个人求职网站履历怎么做公众号运营策划
  • 泰州腾讯网站开发免费自助建站系统大全
  • 网站定向搜索ui设计一个月挣多少钱
  • 网站建设东莞网站伪静态化
  • 免费网站推广怎么做做网站要多钱
  • 企业网站建设财务规划工商个体户年检网上申报
  • 网站教育培训机构排名如何做网站推广广告