每个线程都有自己的空间去暂存数据
当有一份数据在A,B线程之间共享
那么在A线程中改变了B是不会马上知道的
example
/**
* 共享对象
* 多个对象在没有同步的情况下会发生可见性的错误
*/
public class SharingObjects1 {
private static boolean ready;
private static int number;
private static class ReaderThread extends Thread{
@Override
public void run(){
while(!ready){
Thread.yield();
System.out.println(number);
}
System.out.println("thread "+Thread.currentThread().getId()+" over");
}
public static void main(String[] args) {
new ReaderThread().start();
number = 42;
ready = true;
System.out.println("thread "+Thread.currentThread().getId()+" over");
}
}
}
输出:
0
0
0
0
thread 11 over
thread 1 over
同理
package com.taobao.threadlearning.simple;
public class SharingObjects2 {
class SynchronizedInteger{
private int value;
public int getValue() { return value; }
public void setValue(int value) { this.value = value; }
}
}
这段代码也是线程不安全的,当A线程已经调用过set方法,在A线程本地存储的变量写回到公共空间前B线程依然可能通过get方法获得已经过期的数据。
如何解决?
两种方式
A 同步
B Volatile关键字
当一个域声明为volatile类型后,它确保对一个变量的更新以可预见的方式告知其他的线程。volatile变量不会缓存在寄存器或者缓存在在对其他处理器隐藏的地方。所以,读取一个volitile类型的时,总会返回由某一线程所写入的最新值。
当然volatile只能保证可见性,而加锁可以保证可见性和原子性。
以下代码
volatile int i;
public int IncAndGet(){
i++;
return i;
}
任然不能保证在多线程下正常工作,原因 原子性
分享到:
相关推荐
5. **内存屏障**:内存屏障是一种硬件指令,用于确保某些内存操作的顺序,防止编译器和处理器优化导致的数据可见性问题。 在"如何创建UI线程"这个话题中,UI线程(通常称为主线程)负责处理用户界面的事件,如点击...
在"java多线程编程实例_Source"这个压缩包中,你可能会找到以上各种概念的实例代码,通过学习这些代码,你可以更深入地理解Java多线程的实现和应用,提高自己的编程能力。记得实践是最好的老师,尝试运行和修改这些...
在Java中,我们通过定义类(class)来实现封装,使用访问修饰符(如private, public, protected)控制成员变量和方法的可见性。实验可能涉及创建一个类,隐藏内部实现细节,只暴露必要的公共方法供其他类调用。 2. ...
多线程编程的核心是保证三个特性:原子性、可见性和有序性。 - **原子性**:确保操作不可分割,要么全做要么不做,避免并发执行时的中断问题。 - **可见性**:线程间对共享变量的修改能立即被其他线程感知。 - **...
8. **Java内存模型(JMM)**:JMM规定了线程如何共享和访问内存,包括volatile关键字、final域的语义、线程之间的可见性以及 Happens-Before原则,这些都是保证多线程正确性的基础。 9. **线程安全**:线程安全的...
- volatile关键字确保变量在多线程环境下的可见性,但不能保证原子性。 4. **线程通信** - wait(), notify()和notifyAll()是Object类的方法,用于线程间的通信。使用这些方法需要在同步环境中,以避免死锁等问题...
在Java编程语言中,多线程是程序设计中的一个重要概念,尤其在处理高并发和资源优化的场景下...通过观看"Java多线程基础-02、数组定义方式一、访问、注意事项.mp4"这个视频教程,你将能更深入地学习这些重要的知识点。
在iOS开发中,多线程技术是提高应用性能、增强用户...随着iOS系统和硬件的发展,多线程技术在开发中的重要性将越来越显著。掌握GCD等并发编程技术,无疑将帮助开发者更好地发挥iOS平台的性能优势,提升产品的竞争力。
JMM定义了线程如何访问共享变量的规则,保证了多线程环境下的可见性和有序性。volatile确保了线程之间的数据一致性,但并不能保证原子性,因此在某些场景下需要配合synchronized使用。 通过《Java多线程编程实战...
总的来说,Java多线程学习涵盖了线程的创建、同步、通信、调度以及异常处理等多个方面,深入理解和掌握这些知识点对于提升Java程序的性能和复杂性至关重要。通过阅读提供的"Java多线程.pdf"文档,你可以进一步了解和...
- **volatile**:确保多线程环境中的变量可见性和有序性。 - **wait()与notify()**:用于线程间的通信,等待和唤醒其他线程。 - **Lock接口**:提供更灵活的锁机制,如ReentrantLock。 3. **线程池** - **...
2. **volatile关键字**:保证共享变量的可见性,但不保证原子性。 3. **Lock接口与ReentrantLock**:提供更细粒度的锁控制,支持公平锁、非公平锁、读写锁等。 4. **ThreadLocal**:为每个线程提供局部变量副本,...
- volatile保证了变量的可见性,即修改后的值能立即被其他线程看到。 - volatile禁止指令重排序,保证了多线程环境下变量的有序性。 3. **Lock接口** - Lock提供了比synchronized更细粒度的锁控制,如可重入锁、...
3. volatile:保证变量在多线程环境下的可见性,但不保证原子性。 4. Lock接口:提供更细粒度的锁控制,比如可重入、公平性、非阻塞尝试获取锁等。 四、线程通信 1. wait()、notify()和notifyAll():这三个方法...
Java多线程详解 在Java编程中,多线程是一种重要的技术,它使得程序能够同时执行多个任务,提高系统的效率和响应性。本教程将详细讲解Java中的多线程概念,包括...通过实践和不断学习,你将成为一个多线程编程的专家。
- `volatile`关键字:用于标记共享变量,确保多线程环境下的可见性和有序性,但不保证原子性。 - `join()`方法:让当前线程等待另一个线程完成其执行。 4. **线程优先级与调度**:Java的`Thread`类提供了设置线程...
通过这个"多线程demo/java多线程练习"项目,你可以深入学习和实践Java多线程编程,包括线程池的使用、并发工具的应用以及模拟数据库操作时的线程安全问题。这将极大地提高你在实际项目中的问题解决能力。
- **可见性**:使用volatile保证多线程间共享变量的可见性。 - **有序性**:使用volatile、synchronized或java.util.concurrent包中的工具类来保证指令的执行顺序。 通过深入理解以上知识点,开发者可以更好地...
Java多线程是Java编程中的核心概念,它允许程序同时执行多个任务,提高了软件的效率和响应性。在Java中,多线程的实现主要有两种方式:通过继承Thread类和实现Runnable接口。这篇资料深入探讨了Java多线程的相关知识...
在Java并发编程中,线程安全是一个至关重要的概念,它涉及到多线程环境下对共享数据的正确管理和访问。线程安全意味着当多个线程同时访问一个对象或数据时,对象的状态能够保持一致性和完整性,不会因为并发导致数据...