1. 作用范围不同
- static关键字:用于创建类级别的变量或方法,所有类的实例共享同一个static变量的副本。
- volatile关键字:用于确保一个变量在多线程环境中的可见性,使所有线程都能看到最新的变量值。
2. 变量类型不同
- static:可用于变量、方法、初始化块和内部类。
- volatile:仅用于声明变量。
3. 内存模型不同
- static:static变量在内存中有一个存储位置,所有实例共享这一个存储位置。
- volatile:强制线程每次读取volatile变量时都从主内存中获取,每次写入时都写入主内存。
4. 线程安全不同
- static:仅通过将变量声明为static并不能确保线程安全。
- volatile:通过保证变量的可见性,提供了一定的线程安全保障。
5. 性能不同
- static:性能高,因为所有实例共享一个变量副本。
- volatile:可能影响性能,因为每次读写都需要访问主内存。
延伸阅读
static关键字的五个重要作用是什么
1.修饰局部变量
static修饰局部变量时,使得被修饰的变量成为静态变量,存储在静态区。存储在静态区的数据生命周期与程序相同,在main函数之前初始化,在程序退出时销毁。
2.修饰全局变量
全局变量本来就存储在静态区,因此static并不能改变其存储位置。但是,static限制了其链接属性。被static修饰的全局变量只能被该包含该定义的文件访问(即改变了作用域)。
3.修饰函数
static修饰函数使得函数只能在包含该函数定义的文件中被调用。对于静态函数,声明和定义需要放在同一个文件夹中。
4.面向对象中修饰数据成员
被static修饰的数据成员实际上相当于类域中的全局变量。因此,对于类的每个对象来说,它是共有的。它在整个程序中只有一份拷贝,只在定义时分配一次内存,供该类所有的对象使用,其值可以通过每个对象来更新。由于静态数据成员存储在全局数据区,因此,在定义时就要分配内存,这也就导致静态数据成员不能在类声明中定义。
5.面向对象中修饰成员函数
同静态数据成员一样,静态成员函数也是属于类,而不属于任何一个类的实体对象,因此,静态成员函数不含有this指针。同时,它也不能访问类中其它的非静态数据成员和函数。