`

java 并发 竞态条件(1)

    博客分类:
  • Java
阅读更多

竞态条件,说得通俗一点,就是线程A 需要判断一个变量的状态,然后根据这个变量的状态来执行某个操作。

在执行这个操作之前,这个变量的状态可能会被其他线程修改。

看一个例子

import java.util.concurrent.atomic.AtomicLong;


public class LazyInitRace {
	private ExpensiveObject instance=null;
	
	public ExpensiveObject getInstance(){
		if(instance==null){
			instance=new ExpensiveObject();
		}
		return instance;
	}
}

 在LazyInitRace 中包含了一个竞态条件,它可能会破坏这个类的正确性。假定线程A和线程B 同时执行getInstance 方法。A 看到instance 为空,因此A创建一个新的ExpensiveObject实例。B 同样需要判断instance 是否为空。此时的instance是否为空,要取决于不可预测的时序,包括线程的调度方式,以及A 需要花多长时间来初始化ExpensiveObject并设置instance。如果当B检查时,instance为空,那么在两次调用getInstance 时可能会得到不同的对象。

 

线程A和B的执行时序可能是这样的:

 说明:线程B 在执行红色部分代码(判断instance是否为空)时,线程A 还没来得执行完绿色部分的代码。

 

也可能是这样的:

 

有什么解决方案呢?

方案一:内置锁

每个java对象都可以用作一个实现同步的锁。

线程进入内置锁保护的代码块时就拥有锁,执行完这段代码块时就自动释放锁。同一时刻只能有一个线程拥有锁,其他的线程只能等待。也就是说,当线程A 进入内置锁保护的代码块时,其他线程是不能执行这段代码的,只能等待线程A执行完毕。

线程安全的代码如下:

public class LazyInitRace {
	private ExpensiveObject instance=null;
	
	public synchronized ExpensiveObject getInstance(){
		if(instance==null){
			instance=new ExpensiveObject();
		}
		return instance;
	}
}

 

  • 大小: 20.6 KB
  • 大小: 18.8 KB
分享到:
评论

相关推荐

    Java并发编程实战

    2.2.2 示例:延迟初始化中的竞态条件 2.2.3 复合操作 2.3 加锁机制 2.3.1 内置锁 2.3.2 重入 2.4 用锁来保护状态 2.5 活跃性与性能 第3章 对象的共享 3.1 可见性 3.1.1 失效数据 3.1.2 非原子的64位操作 ...

    Java 并发编程实战

    2.2.2 示例:延迟初始化中的竞态条件 2.2.3 复合操作 2.3 加锁机制 2.3.1 内置锁 2.3.2 重入 2.4 用锁来保护状态 2.5 活跃性与性能 第3章 对象的共享 3.1 可见性 3.1.1 失效数据 3.1.2 非原子的64位操作 ...

    java并发编程理论基础精讲

    共享资源与竞态条件: 详解共享资源在多线程环境中的问题,引出竞态条件的概念。 对象锁和监视器: 介绍对象锁的概念,解释如何使用 synchronized 关键字来实现对象级别的同步。 线程间通信: 详细讲解多线程之间...

    Java并发编程(学习笔记).xmind

    竞态条件 基于一种可能失效的观察结果来做出判断或执行某个计算 复合操作:执行复合操作期间,要持有锁 锁的作用 加锁机制、用锁保护状态、实现共享访问 锁的不恰当使用可能会引起程序性能...

    java并发编程:线程基础

    线程的同步与阻塞: 引入多线程访问共享资源可能导致的问题,如竞态条件和数据不一致。介绍如何使用 synchronized 关键字来实现线程的同步和阻塞。 线程间通信: 详解线程间通信的方法,包括 wait、notify 和 ...

    92道Java多线程与并发面试题含答案(很全)

    同步(Synchronization):同步是控制多个线程访问共享资源的方式,以防止数据不一致和竞态条件。Java提供了多种同步机制,包括synchronized关键字、Lock接口和Semaphore类。 线程间通信(Inter-Thread ...

    java多线程安全性基础介绍.pptx

    竞态条件 i++ 读i ++ 值写回i 可见性 JMM 由于cpu和内存加载速度的差距,在两者之间增加了多级缓存导致,内存并不能直接对cpu可见。 各线程之间变量不可见,线程通信通过共享主内存实现。 volatile 仅...

    【并发编程】自定义简单线程池.pdf

    同步机制:讲解如何使用锁、信号量、原子操作等同步机制来避免竞态条件和死锁。 并发模型:介绍不同的并发模型,如生产者-消费者模型、管道模型、消息传递模型等。 并发工具:介绍并发编程中使用的工具和库,如...

    【并发编程】深入理解JMM.pdf

    同步机制:讲解如何使用锁、信号量、原子操作等同步机制来避免竞态条件和死锁。 并发模型:介绍不同的并发模型,如生产者-消费者模型、管道模型、消息传递模型等。 并发工具:介绍并发编程中使用的工具和库,如...

    【并发编程】CAS到底是什么.pdf

    同步机制:讲解如何使用锁、信号量、原子操作等同步机制来避免竞态条件和死锁。 并发模型:介绍不同的并发模型,如生产者-消费者模型、管道模型、消息传递模型等。 并发工具:介绍并发编程中使用的工具和库,如...

    【并发编程】如何优雅使用线程池.pdf

    同步机制:讲解如何使用锁、信号量、原子操作等同步机制来避免竞态条件和死锁。 并发模型:介绍不同的并发模型,如生产者-消费者模型、管道模型、消息传递模型等。 并发工具:介绍并发编程中使用的工具和库,如...

    【并发编程】简单化理解AQS和ReentrantLock.pdf

    同步机制:讲解如何使用锁、信号量、原子操作等同步机制来避免竞态条件和死锁。 并发模型:介绍不同的并发模型,如生产者-消费者模型、管道模型、消息传递模型等。 并发工具:介绍并发编程中使用的工具和库,如...

    【并发编程】volatile的原理我好像又懂了.pdf

    同步机制:讲解如何使用锁、信号量、原子操作等同步机制来避免竞态条件和死锁。 并发模型:介绍不同的并发模型,如生产者-消费者模型、管道模型、消息传递模型等。 并发工具:介绍并发编程中使用的工具和库,如...

    Java多线程编程的优点和缺点

    竞态条件(Race Conditions):多个线程访问共享资源时可能引发竞态条件,导致数据不一致性和程序错误。 死锁(Deadlocks):多线程编程容易出现死锁,即多个线程相互等待对方释放资源的情况,导致程序无法继续执行...

    阿里巴巴java开发手册

    4. **并发控制**:在多线程环境下,要正确地处理并发访问共享资源的问题,避免出现死锁、竞态条件等并发问题。 5. **性能优化**:优化代码以提高性能,包括减少内存占用、降低时间复杂度等方面的优化。 6. **安全性*...

    java关键字Synchronized详解

    这会导致原本同步的代码段出现竞态条件,从而引发程序错误。 为了避免锁膨胀,Java提供了一种称为“偏向锁”的优化策略。偏向锁的主要目的是减少锁竞争,提高并发性能。当一个对象首次被创建时,JVM会自动为其分配...

    leetcode赛车-Concurrency:#JAVA#并发

    术语竞态条件源于线程正在通过临界区竞争的比喻,并且该竞争的结果影响执行临界区的结果。 活力 并发应用程序及时执行的能力被称为活跃度。 最常见的一种活性问题,死锁,以及另外两种活性问题,饥饿和活锁。 僵局 ...

Global site tag (gtag.js) - Google Analytics