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

哈尔滨企业建站模板产品推广平台有哪些

哈尔滨企业建站模板,产品推广平台有哪些,一个网站需要多少钱,浦江建设局网站在 Java 并发编程中,线程同步是确保数据一致性和避免竞争条件的关键手段。synchronized 关键字和 java.util.concurrent.locks.Lock 接口是两种主流的同步工具,各有其设计理念和使用场景。作为 Java 开发者,理解两者的区别不仅有助于选择合适…

在 Java 并发编程中,线程同步是确保数据一致性和避免竞争条件的关键手段。synchronized 关键字和 java.util.concurrent.locks.Lock 接口是两种主流的同步工具,各有其设计理念和使用场景。作为 Java 开发者,理解两者的区别不仅有助于选择合适的工具,还能优化并发应用的性能和可维护性。本文将深入剖析 synchronizedLock 的原理、功能差异及适用场景,并通过 Java 代码展示两者的实际应用。


一、Synchronized 与 Lock 的基本概念

1. Synchronized

synchronized 是 Java 的内置关键字,用于实现线程同步。它基于 JVM 的监视器(Monitor)机制,通过对象锁确保同一时刻只有一个线程访问受保护的代码块或方法。

  • 使用方式
    • 同步代码块:锁定指定对象。
    • 同步方法:锁定当前对象(this)或类对象(Class)。
  • 语法示例
    synchronized (obj) {// 同步代码块
    }
    public synchronized void method() {// 同步方法
    }
    

2. Lock

Lock 是 Java 5 引入的 java.util.concurrent.locks 包中的接口,提供了更灵活的锁机制。常见的实现类包括 ReentrantLock,它通过显式加锁和解锁操作实现同步。

  • 使用方式
    • 手动调用 lock() 加锁,unlock() 解锁。
  • 语法示例
    Lock lock = new ReentrantLock();
    lock.lock();
    try {// 同步代码
    } finally {lock.unlock();
    }
    

二、Synchronized 与 Lock 的核心区别

1. 实现机制

  • Synchronized
    • 基于 JVM 内置的 Monitor 对象。
    • 使用对象头中的 Mark Word 存储锁状态。
    • 通过 monitorentermonitorexit 字节码指令实现。
  • Lock
    • 基于 Java 代码和 AQS(AbstractQueuedSynchronizer)框架。
    • 使用 volatile 变量和 CAS(Compare-And-Swap)管理锁状态。

2. 使用方式

  • Synchronized
    • 隐式加锁和解锁,JVM 自动管理。
    • 无需显式释放锁,异常时自动解锁。
  • Lock
    • 显式加锁和解锁,需手动调用 unlock()
    • 必须在 finally 块中释放锁,否则可能导致死锁。

3. 功能特性

特性SynchronizedLock
可重入性支持支持(ReentrantLock
公平性非公平可选公平(ReentrantLock(true)
中断性不支持支持(lockInterruptibly()
超时尝试不支持支持(tryLock(timeout)
条件变量单一 wait/notify多个 Condition 对象
锁状态查询不支持支持(isLocked()

4. 性能

  • Synchronized
    • JDK 1.6 后优化,引入偏向锁、轻量级锁和重量级锁,性能显著提升。
    • 在低竞争场景下开销小。
  • Lock
    • 基于 AQS,竞争激烈时性能优于重量级锁。
    • 高竞争下 CAS 操作可能导致自旋开销。

5. 异常处理

  • Synchronized:异常后自动释放锁。
  • Lock:异常后若未释放锁,可能导致死锁,需 finally 确保解锁。

三、底层原理剖析

1. Synchronized 的实现

synchronized 依赖 JVM 的 Monitor 机制:

  • 对象头:Mark Word 记录锁状态(无锁、偏向锁、轻量级锁、重量级锁)。
  • 锁升级
    1. 偏向锁:低竞争时偏向首个线程。
    2. 轻量级锁:少量竞争时使用 CAS。
    3. 重量级锁:高竞争时转为 Monitor。
  • 字节码
    public void method() {synchronized (this) {System.out.println("Hello");}
    }
    
    编译后:
    monitorenter
    getstatic java/lang/System.out
    ldc "Hello"
    invokevirtual java/io/PrintStream.println
    monitorexit
    

2. Lock 的实现

ReentrantLock 基于 AQS:

  • 状态变量volatile int state 表示锁状态(0 为未锁,>0 为已锁)。
  • 队列:AQS 维护等待线程的双向链表(CLH 变种)。
  • CAS:通过 compareAndSetState 原子更新状态。
  • 源码解析ReentrantLock.lock):
    public void lock() {sync.acquire(1);
    }
    public final void acquire(int arg) {if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt();
    }
    protected final boolean tryAcquire(int acquires) {Thread current = Thread.currentThread();int c = getState();if (c == 0) {if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}} else if (current == getExclusiveOwnerThread()) {setState(c + acquires);return true;}return false;
    }
    

四、功能对比与使用场景

1. 可重入性

两者都支持可重入:

  • Synchronized
    public synchronized void outer() {inner();
    }
    public synchronized void inner() {System.out.println("Inner called");
    }
    
  • Lock
    Lock lock = new ReentrantLock();
    public void outer() {lock.lock();try {inner();} finally {lock.unlock();}
    }
    public void inner() {lock.lock();try {System.out.println("Inner called");} finally {lock.unlock();}
    }
    

2. 公平性

  • Synchronized:非公平,线程随机获取锁。
  • Lock:支持公平锁:
    Lock fairLock = new ReentrantLock(true); // 公平锁
    

3. 中断性与超时

  • Lock
    Lock lock = new ReentrantLock();
    if (lock.tryLock(1, TimeUnit.SECONDS)) {try {// 操作} finally {lock.unlock();}
    } else {System.out.println("Lock not acquired");
    }
    

4. 条件变量

  • Synchronized:单一 wait/notify
    synchronized (obj) {while (condition) {obj.wait();}obj.notify();
    }
    
  • Lock:多个 Condition
    Lock lock = new ReentrantLock();
    Condition condition1 = lock.newCondition();
    Condition condition2 = lock.newCondition();
    lock.lock();
    try {while (condition) {condition1.await();}condition2.signal();
    } finally {lock.unlock();
    }
    

五、Java 实践:对比 Synchronized 与 Lock

以下通过一个多线程计数器,展示两者的应用。

1. 环境准备

  • 依赖pom.xml):
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>

2. Synchronized 实现

@RestController
@RequestMapping("/sync")
public class SyncCounterController {private int counter = 0;private final Object lock = new Object();@GetMapping("/increment")public String increment() {new Thread(() -> {for (int i = 0; i < 1000; i++) {synchronized (lock) {counter++;}}}).start();return "Synchronized increment started";}@GetMapping("/value")public int getValue() {synchronized (lock) {return counter;}}
}

3. Lock 实现

@RestController
@RequestMapping("/lock")
public class LockCounterController {private int counter = 0;private final Lock lock = new ReentrantLock();@GetMapping("/increment")public String increment() {new Thread(() -> {for (int i = 0; i < 1000; i++) {lock.lock();try {counter++;} finally {lock.unlock();}}}).start();return "Lock increment started";}@GetMapping("/value")public int getValue() {lock.lock();try {return counter;} finally {lock.unlock();}}@GetMapping("/try-increment")public String tryIncrement() throws InterruptedException {new Thread(() -> {for (int i = 0; i < 1000; i++) {if (lock.tryLock()) {try {counter++;} finally {lock.unlock();}}}}).start();return "Try-lock increment started";}
}

4. 主应用类

@SpringBootApplication
public class LockVsSyncApplication {public static void main(String[] args) {SpringApplication.run(LockVsSyncApplication.class, args);}
}

5. 测试

测试 1:基本同步
  • Synchronized
    • 请求:GET http://localhost:8080/sync/increment(10 次)
    • 查询:GET http://localhost:8080/sync/value
    • 结果:10000
  • Lock
    • 请求:GET http://localhost:8080/lock/increment(10 次)
    • 查询:GET http://localhost:8080/lock/value
    • 结果:10000
  • 分析:两者均正确同步,计数器无竞争问题。
测试 2:超时与尝试锁
  • Lock
    • 请求:GET http://localhost:8080/lock/try-increment(10 次)
    • 查询:GET http://localhost:8080/lock/value
    • 结果:可能小于 10000(因 tryLock 不阻塞)。
  • Synchronized:无类似功能。
  • 分析Lock 提供非阻塞选项,适合避免死锁。
测试 3:性能对比
  • 代码
    public class PerformanceTest {private static final int THREADS = 100;private static final int INCREMENTS = 10000;public static void main(String[] args) throws InterruptedException {testSynchronized();testLock();}static void testSynchronized() throws InterruptedException {Object lock = new Object();int[] counter = {0};Thread[] threads = new Thread[THREADS];long start = System.currentTimeMillis();for (int i = 0; i < THREADS; i++) {threads[i] = new Thread(() -> {for (int j = 0; j < INCREMENTS; j++) {synchronized (lock) {counter[0]++;}}});threads[i].start();}for (Thread t : threads) t.join();long end = System.currentTimeMillis();System.out.println("Synchronized: " + (end - start) + "ms, Counter: " + counter[0]);}static void testLock() throws InterruptedException {Lock lock = new ReentrantLock();int[] counter = {0};Thread[] threads = new Thread[THREADS];long start = System.currentTimeMillis();for (int i = 0; i < THREADS; i++) {threads[i] = new Thread(() -> {for (int j = 0; j < INCREMENTS; j++) {lock.lock();try {counter[0]++;} finally {lock.unlock();}}});threads[i].start();}for (Thread t : threads) t.join();long end = System.currentTimeMillis();System.out.println("Lock: " + (end - start) + "ms, Counter: " + counter[0]);}
    }
    
  • 结果(8 核 CPU):
    Synchronized: 152ms, Counter: 1000000
    Lock: 168ms, Counter: 1000000
    
  • 分析:低竞争下 synchronized 略快,因 JVM 优化;高竞争下 Lock 可通过公平性调整性能。

六、使用场景与选择建议

1. Synchronized 适用场景

  • 简单同步需求:代码量少,无需复杂功能。
  • 低竞争环境:偏向锁和轻量级锁高效。
  • 异常安全要求高:无需手动释放锁。

2. Lock 适用场景

  • 复杂同步逻辑:需要条件变量、中断或超时。
  • 高竞争环境:公平锁或非阻塞尝试。
  • 动态控制:需查询锁状态或自定义行为。

3. 选择建议

  • 默认使用 Synchronized:简单场景,代码更简洁。
  • 优先考虑 Lock:需要高级功能或性能优化。

七、优化与实践经验

1. 性能优化

  • 减小锁范围
    synchronized (lock) {int temp = counter; // 读操作无需锁counter = temp + 1; // 仅写操作加锁
    }
    
  • 使用读写锁Lock):
    ReadWriteLock rwLock = new ReentrantReadWriteLock();
    rwLock.readLock().lock();
    

2. 异常处理

  • Lock
    lock.lock();
    try {// 操作
    } catch (Exception e) {log.error("Error occurred", e);
    } finally {lock.unlock();
    }
    

3. 调试技巧

  • jstack:检查锁状态和死锁。
  • VisualVM:监控线程和锁竞争。

八、总结

synchronizedLock 是 Java 并发控制的两种利器,前者简单高效,依赖 JVM 内置机制;后者功能丰富,基于 AQS 提供灵活性。本文从实现原理、功能对比到实践应用,全面展示了它们的区别。测试表明,synchronized 适合简单场景,而 Lock 在复杂需求中更具优势。

http://www.cadmedia.cn/news/13923.html

相关文章:

  • 企业网站建设 安全百度广告电话号码是多少
  • 网站建设项目策划书模板范文免费建立个人网站
  • html5网页制作实例代码霸榜seo
  • 非遗网站建设目的网络营销试卷
  • termux安装wordpress谷歌seo站内优化
  • 外贸网站怎么找客户邯郸seo
  • 网站开发培训网房地产十大营销手段
  • 网站免费建站o网页广告调词平台多少钱
  • 深圳品牌网站建设公司哪家好国家免费职业培训平台
  • 沈阳做网站开发公司网站seo外包靠谱吗
  • 网站个人主页模板线下推广都有什么方式
  • 深圳互联网公司招聘网站建设加推广优化
  • 网站建设责任分解成都新闻最新消息
  • 人民政府网站的信息资源建设惠州关键词排名优化
  • 点石嘉业北京网站建设公司微信小程序开发费用
  • 网站栏目名称大全免费网站免费
  • 高校 网站建设实施方案网络优化培训要多少钱
  • 搜狗网站优化软件百度云盘登录
  • 搜狐快站官网app推广赚钱平台
  • 学校网站建设的意义的主要负责人夸克搜索引擎入口
  • 商务网站建设的应用今日新闻联播主要内容摘抄
  • 教育加盟培训网站建设网上代写文章一般多少钱
  • 高档网站建设公司itme收录优美图片官网
  • 北京高档网站建设经典广告
  • 搭建网站服务器多少钱seo网站内部优化方案
  • wrb网站架构百度优化插件
  • 广西贵港网站建设深圳seo推广外包
  • 品牌营销策划书模板手机优化大师下载
  • 图片生成器免费太原seo网站排名
  • 南昌网站专业制作关键词点击价格查询