赞
踩
目录
线程不安全指的是程序在多线程的执行结果不符合预期。
单线程:
- public class ThreadDemoCounter2 {
- static class Counter {
- private int num = 0;
- public void incr(int count) {
- for (int i = 0; i < count; i++) {
- num++;
- }
- }
-
- public void decr(int count) {
- for (int i = 0; i < count; i++) {
- num--;
- }
- }
-
- public int getNum() {
- return num;
- }
- }
-
- public static void main(String[] args) {
- int count = 100000;
- Counter counter = new Counter();
- counter.incr(count);
- counter.decr(count);
- System.out.println(counter.getNum());
- }
- }
-
- 输出:
- 0
多线程:
- public class ThreadDemoCounter3 {
- static class Counter {
- private int num = 0;
-
- public void incr(int count) {
- for (int i = 0; i < count; i++) {
- num++;
- }
- }
-
- public void decr(int count) {
- for (int i = 0; i < count; i++) {
- num--;
- }
- }
-
- public int getNum() {
- return num;
- }
- }
-
- public static void main(String[] args) throws InterruptedException {
- int count = 10000;
- Counter counter = new Counter();
- Thread t1 = new Thread(() -> {
- counter.incr(count);
- });
- t1.start();
-
- Thread t2 = new Thread(() -> {
- counter.decr(count);
- });
- t2.start();
-
- t1.join();
- t2.join();
-
- System.out.println(counter.getNum());
- }
- }
-
- 输出:
- 最终结果:0
- public class ThreadDemoCounter4 {
- static class Counter {
- int num = 0;
-
- public int incr(int count) {
- for (int i = 0; i < count; i++) {
- num++;
- }
- return num;
- }
-
- public int decr(int count) {
- for (int i = 0; i < count; i++) {
- num--;
- }
- return num;
- }
- }
-
- public static void main(String[] args) throws InterruptedException {
- int count = 10000;
- Counter counter = new Counter();
-
- final int[] num1 = new int[1];
- Thread t1 = new Thread(() -> {
- num1[0] = counter.incr(count);
- });
- t1.start();
-
- final int[] num2 = new int[1];
- Thread t2 = new Thread(() -> {
- num2[0] = counter.decr(count);
- });
- t2.start();
-
- t1.join();
- t2.join();
-
- System.out.println(num1[0] + num2[0]);
- }
- }
-
-
- 输出:
- 100000
- public class ThreadDemoCounter5 {
- static class Counter {
- private int num = 0;
-
- public void incr(int count) {
- for (int i = 0; i < count; i++) {
- num++;
- }
- }
-
- public void decr(int count) {
- for (int i = 0; i < count; i++) {
- num--;
- }
- }
-
- public int getNum() {
- return num;
- }
- }
-
- public static void main(String[] args) throws InterruptedException {
- int count = 10000;
- ThreadDemoCounter3.Counter counter = new ThreadDemoCounter3.Counter();
- Thread t1 = new Thread(() -> {
- counter.incr(count);
- });
- t1.start();
- t1.join();
-
- Thread t2 = new Thread(() -> {
- counter.decr(count);
- });
- t2.start();
- t2.join();
-
- System.out.println(counter.getNum());
- }
- }
-
- 输出
- 0
- public class ThreadDemoCounter6 {
- private static boolean flag = true;
-
- public static void main(String[] args) {
- Thread t1 = new Thread(() -> {
- System.out.println("线程1:开始执行" + LocalDateTime.now());
-
- while(flag ) {
- }
- System.out.println("线程1:结束执行" + LocalDateTime.now());
- });
- t1.start();
-
- Thread t2 = new Thread(() -> {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("线程2:修改flag = false" + LocalDateTime.now());
- flag = false;
- });
- t2.start();
- }
- }
-
- 输出:
- 线程1:开始执行2022-03-29T09:20:29.894
- 线程2:修改flag = false2022-03-29T09:20:30.856
可以发现·,线程2修改全局变量之后,理论上,线程1应该结束,并输出“线程1:结束执行 + 时间”,但线程1却在一直在执行,并没有感知到全局变量flag的变化,这就是内存可见性问题。
a. 线程之间的共享变量存在 主内存
b. 每⼀个线程都有⾃⼰的 "⼯作内存"
c. 当线程要读取⼀个共享变量的时, 会先把变量从主内存拷⻉到⼯作内存, 再从⼯作内存读取数据.
为了提供性能,编译器和处理器会在保证逻辑不变的情况下,对指令做重排序。但这个优化非常地复杂。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。