1 synchronized与volatile
- synchronized:保证可见性和原子性,线程安全;
- volatile:保证可见性,不保证原子性,线程不安全。
可见性:变量值修改后,立即更新到公共内存区,保证其他线程是可见的。
原子性:一个线程从获取变量,到变更结束,不会被其他线程改变。
2 测试
2.1 volatile
package com.monkey.java_study.security;
import java.util.ArrayList;
import java.util.List;
/**
* 线程安全测试.
*
* @author xindaqi
* @date 2021-10-26 16:27
*/
public class ThreadSecurityTest {
private volatile int var1;
private int var2;
public ThreadSecurityTest() {
}
public void setVar1(int var1) {
this.var1 = var1;
}
public int getVar1() {
return var1;
}
public void setVar2(int var2) {
this.var2 = var2;
}
public int getVar2() {
return var2;
}
public void increaseVar1() {
var1 += 1;
}
public void increaseVar2() {
var2 += 1;
}
public static void volatileTest() throws InterruptedException {
ThreadSecurityTest threadSecurityTest = new ThreadSecurityTest();
threadSecurityTest.setVar1(0);
List<Thread> threadList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Thread t1 = new Thread(() -> {
threadSecurityTest.increaseVar1();
System.out.println(">>>>>>>>>>var1:" + threadSecurityTest.getVar1());
});
t1.start();
threadList.add(t1);
}
for (Thread thread : threadList) {
thread.join();
}
System.out.println(">>>>>>>>>>Finally:" + threadSecurityTest.getVar1());
}
public static void synchronizedTest() throws InterruptedException {
ThreadSecurityTest threadSecurityTest = new ThreadSecurityTest();
threadSecurityTest.setVar2(0);
List<Thread> threadList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Thread t1 = new Thread(() -> {
synchronized (threadSecurityTest) {
threadSecurityTest.increaseVar2();
System.out.println(">>>>>>>>>>var2:" + threadSecurityTest.getVar2());
}
});
t1.start();
threadList.add(t1);
}
for (Thread thread : threadList) {
thread.join();
}
System.out.println(">>>>>>>>>>Finally:" + threadSecurityTest.getVar2());
}
@Override
public String toString() {
return "ThreadSecurityTest{" +
"var1=" + var1 +
", var2=" + var2 +
'}';
}
public static void main(String[] args) throws InterruptedException {
ThreadSecurityTest.volatileTest();
}
}
由结果可知,使用volatile修饰的变量,无法保证线程安全。
2.2 synchronized
package com.monkey.java_study.security;
import java.util.ArrayList;
import java.util.List;
/**
* 线程安全测试.
*
* @author xindaqi
* @date 2021-10-26 16:27
*/
public class ThreadSecurityTest {
private volatile int var1;
private int var2;
public ThreadSecurityTest() {
}
public void setVar1(int var1) {
this.var1 = var1;
}
public int getVar1() {
return var1;
}
public void setVar2(int var2) {
this.var2 = var2;
}
public int getVar2() {
return var2;
}
public void increaseVar1() {
var1 += 1;
}
public void increaseVar2() {
var2 += 1;
}
public static void volatileTest() throws InterruptedException {
ThreadSecurityTest threadSecurityTest = new ThreadSecurityTest();
threadSecurityTest.setVar1(0);
List<Thread> threadList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Thread t1 = new Thread(() -> {
threadSecurityTest.increaseVar1();
System.out.println(">>>>>>>>>>var1:" + threadSecurityTest.getVar1());
});
t1.start();
threadList.add(t1);
}
for (Thread thread : threadList) {
thread.join();
}
System.out.println(">>>>>>>>>>Finally:" + threadSecurityTest.getVar1());
}
public static void synchronizedTest() throws InterruptedException {
ThreadSecurityTest threadSecurityTest = new ThreadSecurityTest();
threadSecurityTest.setVar2(0);
List<Thread> threadList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Thread t1 = new Thread(() -> {
synchronized (threadSecurityTest) {
threadSecurityTest.increaseVar2();
System.out.println(">>>>>>>>>>var2:" + threadSecurityTest.getVar2());
}
});
t1.start();
threadList.add(t1);
}
for (Thread thread : threadList) {
thread.join();
}
System.out.println(">>>>>>>>>>Finally:" + threadSecurityTest.getVar2());
}
@Override
public String toString() {
return "ThreadSecurityTest{" +
"var1=" + var1 +
", var2=" + var2 +
'}';
}
public static void main(String[] args) throws InterruptedException {
ThreadSecurityTest.synchronizedTest();
}
}
由测试结果可知,使用synchronized关键字的对象,保证对象属性顺序执行,即线程安全。
3 小结
- synchronized线程安全;
- volatile线程不安全。
【参考文献】
[1]https://www.cnblogs.com/heilyeah/p/6594122.html
[2]https://www.cnblogs.com/xuqiudong/p/3952827.html
[3]https://blog.csdn.net/qq_33591903/article/details/81486754